maoja
maoja

Reputation: 13

How can I create a bash function to document bash aliases

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

Answers (2)

Ed Morton
Ed Morton

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

Cyrus
Cyrus

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

Related Questions