Reputation: 13
I'm trying to write a bash function that only uses grep,awk,sed to print out documentation for bash aliases.
I want to use ### as a documentation header for a section of related aliases.
I want to use ## as a documentation string for a description of an alias
An example ~/.bash_aliases file would look like this
### Docker
## List running containers
alias drc="docker ps -a | grep 'Up'"
## List IDs of running containers
alias didr="docker ps -aq | grep 'Up'"
## List IDs of stopped containers
alias dids="docker ps -aq | grep 'Exited' | awk '{print $1}'"
### Ansible
## Run ansible-playbook
alias ap='ansible-playbook'
## Run ansible-playbook on local host
alias apl='ansible-playbook -c local'
Given the .bash_aliases file above I would like to create a bash function named "aliases" that prints the following output
Docker
-------------------------------------------------
drc - List running containers
didr - List IDs of running containers
dids - List IDs of stopped containers
Ansible
-------------------------------------------------
ap - Run ansible-playbook
apl - Run ansible-playbook on local host
I would like to put the "aliases" function in the top of my .bash_aliases file so that when I source the .bash_aliases file I can just run "aliases" to see my documentation.
I saw something at the bottom of this thread https://unix.stackexchange.com/questions/128736/how-to-document-my-custom-bash-functions-and-aliases that appeared to come close to a solution. I've been tweaking it for quite a while and doing lots of google searches but I'm still struggling to get the results I want.
I would appreciate any help. Thanks!
UPDATE:
Thanks to the answer from Ed Morton and the answers to these other questions
I was able to come up with a solution.
Here is an example ~/.bash_aliases file now
IFS='' read -r -d '' VAR <<'EOF'
sub(/^###[[:space:]]+/,"") {
printf "\n%s%s\n----------------------------------------------------------\n", rs, $0
rs = "\n\n"
}
sub(/^##[[:space:]]+/,"") {
desc = $0
}
$1 == "alias" && sub(/=.*/,"",$2) {
printf "%-10s - %s\n", $2, desc
}
EOF
function aliases() {
echo
grep -A10000 "^###" ~/code/bash_aliases/.bash_aliases | awk -f <(echo "$VAR")
echo
}
### Docker
## List running containers
alias drc='docker ps -a | grep 'Up''
## List IDs of running containers
alias didrc='docker ps -aq | grep "Up"'
## List IDs of stopped containers
alias dids='docker ps -aq | grep "Exited" | awk "{print $1}"'
### Ansible
## Run ansible-playbook
alias ap='ansible-playbook'
## Run ansible-playbook on local host
alias apl='ansible-playbook -c local'
After you run
source ~/.bash_aliases
you can run
aliases
The documented aliases will be displayed.
Upvotes: 0
Views: 554
Reputation: 204548
sed is an excellent tool for simple substitutions on a single line but for any other text manipulation you should use awk and once you are using awk you don't need to additionally do anything with grep or sed
$ cat tst.awk
sub(/^###[[:space:]]+/,"") {
printf "%s%s\n---------------\n", rs, $0
rs = "\n\n"
}
sub(/^##[[:space:]]+/,"") {
desc = $0
}
$1 == "alias" && sub(/=.*/,"",$2) {
printf "%s\t- %s\n", $2, desc
}
$ awk -f tst.awk file
Docker
---------------
drc - List running containers
didr - List IDs of running containers
dids - List IDs of stopped containers
Ansible
---------------
ap - Run ansible-playbook
apl - Run ansible-playbook on local host
All of the sed language constructs to do anything across multiple lines became obsolete in the mid-1970s when awk was invented.
Upvotes: 1
Reputation: 88929
With sed. As first step for you:
sed -nE 's/^### (.*)/\n\1\n-------/p;TA;b;:A;s/^## (.*)/\1/;tX;b;:X;h;n;s/^alias (.*)=.*/\1\t\t- /;G;s/\n//p' ~/.bash_aliases
Output:
Docker ------- drc - List running containers didr - List IDs of running containers dids - List IDs of stopped containers Ansible ------- ap - Run ansible-playbook apl - Run ansible-playbook on local host
Upvotes: 1