Branching Many Ways
Problem
You have a series of comparisons to make, and the if/then/else is getting pretty long and
repetitive. Isn’t there an easier way?
Solution
Use the case statement for a multiway branch:
case $FN in
*.gif) gif2png $FN
;;
*.png) pngOK $FN
;;
*.jpg) jpg2gif $FN
;;
*.tif | *.TIFF) tif2jpg $FN
;;
*) printf "File not supported: %s" $FN
;;
esacThe equivalent to this using if/then/else statements is:
if [[ $FN == *.gif ]]
then
gif2png $FN
elif [[ $FN == *.png ]]
then
pngOK $FN
elif [[ $FN == *.jpg ]]
then
jpg2gif $FN
elif [[ $FN == *.tif || $FN == *.TIFF ]]
then
tif2jpg $FN
else
printf "File not supported: %s" $FN
fiDiscussion
The case statement will expand
the word (including parameter substitution) between the case and the in keywords. It will then try to match the
word with the patterns listed in order. This is a very powerful feature
of the shell. It is not just doing simple value comparisons, but string
pattern matches. We have simple patterns in our example: *.gif matches any character sequence (signified
by the *) that ends with the literal characters .gif.
Use |, a vertical bar meaning logical OR, to separate different
patterns for which you want to take the same action. In the example
above, if $FN ends either with
.tif or .TIFF then the pattern will match and the
(fictional) tif2jpg command will be
executed.
Use the double semicolon to end the set of statements or else bash will continue executing into the next set of statements.
There is no else or default keyword ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access