bash_notes
This is an old revision of the document!
Table of Contents
tasks
list file names within a specific range
In bash, we can use a sequence expression
to list files within a specific range. For example
$ echo file{18..21}.txt file18.txt file19.txt file20.txt file21.txt
The sequence expression takes the form {x..y[..incr]}
, where x and y are either integers or single characters, and incr, an optional increment, is an integer. It is part of Bash's brace expansion feature.
Ref:
- https://www.gnu.org/software/bash/manual/html_node/Brace-Expansion.html - documentation on Bash's brace expansion feature.
- https://superuser.com/questions/236484/list-files-numbered-in-a-specific-range - where I came across the above snippet. Dennis Williamson's reply is pretty comprehensive; provides alternatives solutions; addresses corner cases; high information density. It is worth reading it end to end.
Possible use cases:
- To list files
ls file{18..21}.txt
- Use a for loop to run a command on each of them
for file in file{18..21}.txt ...
tags | list file names with a range
dummy
useful links
- https://mywiki.wooledge.org/ArithmeticExpression - Arithmetic Expansion
getopts
useful articles
- https://sookocheff.com/post/bash/parsing-bash-script-arguments-with-shopts/ - Parsing bash script options with getopts
Shell
what is the use of histappend?
code snippets
getopts shift OPTIND
shift "$((OPTIND-1))"
Notes:
- The quotes are important for reasons explained in https://unix.stackexchange.com/questions/214141/explain-the-shell-command-shift-optind-1/
check if an integer is in an interval
current_minute=`date +'%M'` clean_up_start_minute=40 clean_up_end_minute=50 if (( $current_minute >= $clean_up_start_minute )) && (( $current_minute < $clean_up_end_minute )) ; then /* do something */ fi
$ (( 5 >= 15 )) && (( 5 < 30 )) && echo 1 || echo 0 0 $ (( 15 >= 15 )) && (( 15 < 30 )) && echo 1 || echo 0 1 $ (( 20 >= 15 )) && (( 20 < 30 )) && echo 1 || echo 0 1 $ (( 30 >= 15 )) && (( 30 < 30 )) && echo 1 || echo 0 0 $ (( 35 >= 15 )) && (( 35 < 30 )) && echo 1 || echo 0 0
check if an integer is equal to another integer
tags | equality
current_minute=`date +'%M'` clean_up_minute=15 if [ "$current_minute" -eq "$clean_up_minute" ]; then /* do something */ fi
It works for both positive and negative integers.
$ [ 15 -eq 2 ] && echo 1 || echo 0 0 $ [ 15 -eq 15 ] && echo 1 || echo 0 1 $ [ -15 -eq 15 ] && echo 1 || echo 0 0 $ [ -15 -eq -15 ] && echo 1 || echo 0 1
But not for floating point numbers
$ [ 1.5 -eq 2 ] && echo 1 || echo 0 bash: [: 1.5: integer expression expected 0 $ [ 15 -eq 2.0 ] && echo 1 || echo 0 bash: [: 2.0: integer expression expected 0 $ [ 2.0 -eq 2.0 ] && echo 1 || echo 0 bash: [: 2.0: integer expression expected 0
Scripting
echo a string with multiple spaces
Put the variable in double quotes to prevent field splitting
echo "$a"
Example:
$ a='^ foo|' $ echo $a ^ foo| $ echo "$a" ^ foo|
search tags | string concatenation multiple spaces
stackoverflow links I came across
- check if a number is greater than something
- compare numbers
add an element to an array
appliances=("AC" "TV" "Mobile" "Fridge" "Oven" "Blender") appliances+=("Dish Washer") for appliance in "${appliances[@]}" do echo $appliance done
languages=("PHP" "MySQL" "Bash" "Oracle") languages[${#languages[@]}]="Python" for language in "${languages[@]}" do echo $language done
fruits=("Banana" "Mango" "Watermelon" "Grape") fruits=(${fruits[@]} "Jack Fruit") for fruit in "${fruits[@]}" do echo $fruit done
men=("John" "Watson" "Micheal") women=("Lisa" "Ella" "Mila") people=(${men[@]} ${women[@]}) for person in "${people[@]}" do echo $person done
Ref:-
- https://linuxhint.com/bash_append_array/ - well written but the information density is low. So I just summarized the points here and renamed the variables a bit.
bash_notes.1649284701.txt.gz · Last modified: 2022/04/06 22:38 by raju