How to use "case" statement in Bash

Aug 17, 2023#bash

The case statement in Bash is similar to the switch statement found in many other programming languages. Both constructs provide a way to perform multi-way branching based on the value of a variable or expression. They offer a more organized and readable alternative to using multiple if-else statements when dealing with multiple conditional cases.

A case statement in Bash has the following syntax:

case value in
  pattern1)
    # commands to execute if value matches pattern1
    ;;
  pattern2)
    # commands to execute if value matches pattern2
    ;;
  ...
  *)
    # commands to execute if value does not match any pattern
    ;;
esac

Here’s a comprehensive list of rules and guidelines:

  • The value can be any variable or expression that you want to check.
  • The patterns can be any strings, numbers, wildcards, ranges, or regular expressions.
  • Each pattern must be followed by ).
  • The double semicolon ;; marks the end of each block of code.
  • The asterisk * is a special pattern that matches anything and acts as a default case.
  • You can use the | (pipe) character to separate multiple patterns within a single case block.
  • The exit status of a case statement is the exit status of the last command executed within the matched pattern block.

Here is an example of using a case statement in bash to print different messages based on the day of the week:

#!/bin/bash

# get the current day name
day=$(date +%A)

# use a case statement to print different messages
case $day in
  Monday)
    echo "Hello, it's Monday. Have a great start of the week!"
    ;;
  Tuesday)
    echo "Hello, it's Tuesday. Keep up the good work!"
    ;;
  Wednesday)
    echo "Hello, it's Wednesday. You are halfway through the week!"
    ;;
  Thursday)
    echo "Hello, it's Thursday. The weekend is almost here!"
    ;;
  Friday)
    echo "Hello, it's Friday. Time to celebrate!"
    ;;
  Saturday)
    echo "Hello, it's Saturday. Enjoy your weekend!"
    ;;
  Sunday)
    echo "Hello, it's Sunday. Have a relaxing day!"
    ;;
  *)
    echo "Sorry, I don't recognize the day."
    ;;
esac

If you run this script, you will see a different message depending on the current day. For example, if today is Friday, you will see:

Hello, it's Friday. Time to celebrate!

Using wildcards (*)

In Bash, the wildcard character is used as a placeholder to represent any sequence of characters. It’s often used in file and directory operations, as well as in string matching. In the context of a case statement, the wildcard character can be used to match various values based on a specified pattern.

Wildcards are useful for selecting files or directories that share a common pattern, such as extension, prefix, or suffix.

#!/bin/bash

filename="document.txt"

case "$filename" in
  *.txt)
    echo "Text file detected."
    ;;
  *.jpg|*.png)
    echo "Image file detected."
    ;;
  *)
    echo "Unknown file type."
    ;;
esac

# Output:
# Text file detected.

Using ranges ([a-z])

In the context of a case statement, ranges can be used to match characters within a specific range against a given value.

Ranges are specified using square brackets [ ] and a hyphen - between the starting and ending characters of the desired range. For example, [a-z] represents all lowercase letters from ‘a’ to ‘z’, inclusive. Similarly, [0-9] represents all digits from 0 to 9.

#!/bin/bash

grade="B"

case "$grade" in
  [A-C])
    echo "Passing grade."
    ;;
  [D-F])
    echo "Failing grade."
    ;;
  *)
    echo "Invalid grade."
    ;;
esac

# Output:
# Passing grade.

A complex example

Here’s an example that performs different arithmetic operations on two numbers based on the user’s choice. It also uses the if statement to check for zero division or modulus errors.

#!/bin/bash

echo "Enter two numbers:"
read num1 num2
echo "Choose an operation:"
echo "1 - Addition"
echo "2 - Subtraction"
echo "3 - Multiplication"
echo "4 - Division"
echo "5 - Modulus"
read op
case $op in
  1) echo "$num1 + $num2 = $((num1 + num2))";;
  2) echo "$num1 - $num2 = $((num1 - num2))";;
  3) echo "$num1 * $num2 = $((num1 * num2))";;
  4) if [ $num2 -eq 0 ]; then
       echo "Cannot divide by zero"
     else
       echo "$num1 / $num2 = $((num1 / num2))"
     fi;;
  5) if [ $num2 -eq 0 ]; then
       echo "Cannot compute modulus by zero"
     else
       echo "$num1 % $num2 = $((num1 % num2))"
     fi;;
  *) echo "Invalid operation";;
esac

You can test this script with different numbers and operations and see the output:

Enter two numbers:
45 10
Choose an operation:
1 - Addition
2 - Subtraction
3 - Multiplication
4 - Division
5 - Modulus
1
45 + 10 = 55