no matter how long you've been using it, bash is an endless treasure trove of hidden gems thirsting to make your life better. here is a small tasting flight of favorite bash friends I've remembered to write down.
My personal rule of thumb: if I've typed something more than twice, it's time to turn it into a macro.
When have you ever changed directories and not wanted to see the contents of your new location? Rarely.
# cd+ls, only the most used pair of commands of all time ever
function cl() {
cd $@; ls;
}
Here, $@
redirects all of cl
's parameters to cd
.
On a related note, who wants to type three characters every time they have to go up another directory level? Let's simplify upward navigation:
alias .='cl ..'
alias ..='cl ../..'
alias ...='cl ../../..'
alias ....='cl ../../../..'
alias .....='cl ../../../../..'
Jump to your most recent prior location.
alias back='cl -'
Part of exploding your bash-mind is realizing that within this sandbox, you are blessed and cursed with ultimate power, and every character displayed in this terminal is an illusion built atop your personal sandbox of arbitrary inputs and outputs.
Changing your bash prompt to display user@host:directory
. The first two are more useful if you spend a lot of time ssh'd into other machines.
export PS1='$(whoami)@$(hostname):$(pwd)$ '
sh script.sh
and ./script.sh
run the script within a subshell. If you have export
s that you want to persist in your current shell, you need to use source
.
Give user a y/n prompt.
read -r -p "Are You Sure? [y/n] " input
case "$input" in
[yY])
# do something
;;
*)
# do something else (or just exit)
exit 1
;;
esac
cut
, sed
, and awk
, in decreasing order of simplicity and conversely increasing order of power, are the holy trifecta of slice-n-dice programs.
Selecting every k
th of N lines by modular arithmetic.
alias even="awk 'NR % 2 == 0'"
alias odd="awk 'NR % 2 == 1'"
Awkwardly, although arrays in bash are zero-indexed, this seems to be one-indexed, so you know what you're getting into.
$ for i in {1..10}; do echo $i; done | awk 'NR % 2 == 0'
2
4
6
8
10
Searching for something, and also seeing the lines before and after it.
grep -A1 -B1 ...
squeeze consecutive whitespace & trim beginning
alias reduce="tr -s ' ' | sed -e 's/^[[:space:]]*//'"
extract first nonwhitespace field
alias firstarg="reduce | cut -d' ' -f1"
Cut off the first line:
tail -n +2
Cut off the last line:
sed \$d
Cut off the last field (as specified by cut
's -d
delimiter option) from a file.
This reverses the line, cuts out the now-first field, then reverses the line back again.
cat file.txt | rev | cut -d' ' -f1 | rev
tr
(short for “translate”) can be used to transform standard output with substitution or deletion of selected characters.
Transforming a string to uppercase:
> echo "HelLo wOrLd" | tr a-z A-Z
HELLO WORLD
Put all words in a string onto their own line:
> echo "One fish two fish" | tr -cs 'a-zA-Z0-9' '[\n*]'
One
fish
two
fish
One-line Caesar cipher:
> echo "Caesar Cipher" | tr 'A-Za-z' 'N-ZA-Mn-za-m'
Pnrfne Pvcure
tac
!!
jq
wow https://stackoverflow.com/questions/3004811/how-do-you-run-multiple-programs-in-parallel-from-a-bash-script