# Brace expansion#{X,Y} # X Y{X,Y}.txt # X.txt Y.txt{1..10} # 1 2 3 4 5 6 7 8 9 10{1..10..2} # 1 3 5 7 9# Special variables#$# # Number of arguments to script/function$1 # First argument$9 # Ninth argument (NOTE: there is no $10 and higher)"$@" # All arguments as a separate quoted strings"$*" # All arguments as a single string separated by # first IFS character# IFS is the string of characters that act as delimeters# (for example, in loops). If unset, it's equal to the# sequence <space><tab><newline>.# Length of a variable#MYVAR=/path/to/file/file.tar.gz${#MYVAR} # 25# Variable manipulation#${MYVAR%.*} # /path/to/file/file.tar${MYVAR%%.*} # /path/to/file/file${MYVAR#*/} # path/to/file/file.tar.gz${MYVAR##*/} # file.tar.gz${MYVAR/file/newfile} # /path/to/newfile/file.tar.gz${MYVAR//file/newfile} # /path/to/newfile/newfile.tar.gz${MYVAR:1:4} # path${MYVAR:(-6):3} # tar# Setting defaults#${MYVAR:-default} # Return $MYVAR, or "default" if unset${MYVAR:=default} # Set $MYVAR to "default" if unset${MYVAR:+default} # Return "default" if $MYVAR set${MYVAR:?error} # Exit with "error" if $MYVAR unset# Variable variables#VAR1="Hello world"VAR2="VAR1"${!VAR2} # Hello world# Arrays#MYARRAY=("element0" "element1" "element2")MYARRAY[3]="element3"${MYARRAY[0]} # element0${MYARRAY[-1]} # element3${MYARRAY[@]} # element0 element1 element2 element3${MYARRAY[@]:1:2} # element1 element2${!MYARRAY[@]} # 0 1 2 3# Size of an array#${#MYARRAY[@]} # 4# Remove an element from an array#unset MYARRAY[3]# Arrays are actually a special case of dictionaries,# which hold key/value pairs. In an array, keys are just# 0-indexed numbers. Dictionaries work exactly the same# as arrays, except rather than referencing/setting# elements by number, you reference and set them by key.# Create a dictionary#declare -A MYDICT# Math#$(( 1 + 2 )) # 3$RANDOM # Random-ish number# Loop over lines in a file#cat $FILE | while read -r LINE; do # Do stuff with $LINEdone# Loop over filenames with spaces#while IFS= read -d '' -r FILE; do # Do stuff with $FILEdone < <(find $DIR -type f -print0)# The advantage this has over other approaches is that it# doesn't create a subshell, so you can use variables set# within the loop elsewhere. We need to temporarily# override IFS because our list is null-separated; the# space between the -d and the '' (an empty string, which# Bash interprets as the null character) is *required*.