Bash Reference Sheet
This file is work in progress. I’ll add to it whenever I find a useful function.
Bash reference
- TLDP
- The [bash man page] from the Gnu Documentation
- Bash hackers wiki
- This brief course from the City College of SF.
Other posts on Bash
Printing
man printf # man page
man 3 printf # important details about conversion specifiers
From the manpage:
Each conversion specification is introduced by the character
%
, and ends with a conversion specifier. In between there may be (in this order) zero or more flags, an optional minimum field width, an optional precision and an optional length modifier.
azizcodes$ seq 20 | xargs printf '%6.2f %6.2f\n'
1.00 2.00
3.00 4.00
5.00 6.00
7.00 8.00
9.00 10.00
11.00 12.00
13.00 14.00
15.00 16.00
17.00 18.00
19.00 20.00
Another clever way to sum numbers
Not a good way to sum a large list of numbers tho
echo $(seq 10 | tr '\n' '+')0 | bc
IFS (Internal Field Separator) and Expansions
See the bash man page for info on that. I will illustrate the result of word splitting after expansion for now.
azizcodes$ for k in "hi there"; do echo $k; done
The result is
hi there
However,
azizcodes$ message="hi there";for k in $message; do echo $k; done
The result is
hi
there
Flattening folders
I used this command to flattend the directory:
azizcodes$ find target/ -mindepth 2 -type f -exec mv -i '{}' target/ ';'
See flattening for an explanation.
Merge text files into one big file
azizcodes$ for k in $(ls); do cat $k >> notes.md; done
Getting the week number for a date
azizcodes$ date -d "2021-03-25" +%W
returns the number of mondays that passed since the start of the year until this date.
Summing a list of numbers
azizcodes$ seq 10 | awk '{s+=$1} END {print s}'
Reading long files
azizcodes$ for k in {1..115}; do echo $k,$(($k+5)); done|column -t -s,|less
For Loops
If you remember, I had underscores in the beginning of the post titles to mark scripts I wrote. After a while, I decided this was unncessary and actually ugly. However I had 44 posts. Here is how to edit them all at once.
azizcodes$ for i in *.md; do sed -i '' -e '3 s/_//' $i; done
Directory Listing
This is how I can easily know how many files I have in a directory
azizcodes$ ls | nl
Here is how to list the file sizes
azizcodes$ du -sh *
Which file was modified most recently?
azizcodes$ ls -t1
Files
Print a file showing line numbers
azizcodes$ x=0;while read line; do x=$(($x+1));echo $x $line; done < file.txt
Similar to, but not the same as
azizcodes$ nl file.txt
which shows line numbers but not counting the blank lines.
Copying Code
Suppose you are copying python code wich starts with >>>
out of your terminal. Here is how to get rid of it using heredocs
azizcodes$ cat << EOF | sed '/^>>> /!d' | sed 's/>>> //'
> >>> import pandas as pd
> >>> import matplotlib.pyplot as plt
> >>> import numpy as np
> >>> np.random.rand(5)
> array([0.94419688, 0.08191008, 0.49942109, 0.92635266, 0.03367809])
> EOF
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
np.random.rand(5)
Note: this is easier using Vim’s Visual blocks, or even the s
command in Vim.
HTML lists from Markdown lists
Similarly, suppose you are translating a numbered list into html from markdown,
$ cat << eof | sed 's/.\. //'| sed -E 's/(.*)/<li>\1<\/li>/'
Of course the above is easier with Vim by using the same regex.
Loops
Very simple
$ for k in {1..10}; do echo $k, $(($k*2)); done
1, 2
2, 4
3, 6
4, 8
5, 10
6, 12
7, 14
8, 16
9, 18
10, 20
Arguments
Defining the following code as args.sh
:
#!/bin/bash
# add this script to the bash reference sheet
# Quick reminder on arguments in bash
echo \$1 = $1 # 1st arg
echo \$2 = $2 # 2nd arg
echo \"\$1\" = "$1" # 1st arg
echo \$0 = $0 # name of script
echo \$@ = $@ # number of args, array
echo \$# = $# # number of args, number
Let’s test the above code with some arguments.
$ ./args.sh one two three four
$1 = one
$2 = two
"$1" = one
$0 = ./args.sh
$@ = one two three four
$# = 4