====== Shell ====== ===== Block comment ===== With "END" being just an example of any random string that must not appear in the commented section: : << 'END' sleep 1 END ===== Iterate over a list as a string ===== Different options: # option 1, without variable for x in a b c; do echo $x; done # option 2, with string list="a b c" for x in $list; do echo $x; done # only works with sh and bash for x in ${=list}; do echo $x; done # only works with zsh for x in $(echo $list}; do echo $x; done # works with any shell # option 3, with an array list=(a b c) for x in $list; do echo $x; done ===== Do something recursively on all files ===== Use ''find'', with ''{}'' being the file name: find . -type f -exec {} \; find -iname "" -exec {} \; Manual solution: #!/bin/sh function search_dir() { DIR=$1; for file in $DIR/*; do if [[ -f $file ]]; then echo "Do something with $file" fi; done for element in $DIR/* ; do if [[ -e $element && -d $element && \ $(basename "$element") != ".." && \ $(basename "$element") != "." ]]; then search_dir "$element"; fi; done; } search_dir "." ===== Misc ===== * **Default value for variable**: ${:-} * **Get directory of current script** (for instance in order to run a script that is stored in the same directory, or in a known relative path): BASEDIR=$(dirname "$0") * **echo to stderr**, just redirect the output: echo "foo" 1>&2 * **Convert dash-time to ISO** (2024-04-21_15-50-30 to 2024-04-21T15:50:30, for instance to use it as input for ''date''): sed -r "s/([0-9]{4})-([0-9]{2})-([0-9]{2})_([0-9]{2})-([0-9]{2})-([0-9]{2})/\1-\2\-3T\4:\5:\6/" * **Get target name of symbolic link**: readlink * **Execute command**: var=`cat file` var=$(cat file) * **Evaluate mathematical expression** (''zsh'' also supports floating-point operations): echo $((2*3)) * **time with redirected output** (also works for groups of commands): time (cat file1 > file2) time (cat file1 > /dev/null; sync) * **Check number of arguments and print usage:** if [[ $# -lt 2 ]]; then echo "Usage: foo.sh " 1>&2 exit 1 fi * **Load command output as a file:** diff <(grep x file1) <(grep y file2) * **Remove extension from file name:** ${f%.png} # with all shells ${f:r} # only zsh