1. Overview

In programming, a case statement is used to execute different sets of commands based on the value of a variable. It provides a concise and readable way for handling multiple conditions in a script. Each case option represents a single condition and executes a set of commands if the condition is true. However, in some situations, we may have many matching options for a particular case.

In this tutorial, we’ll explore how to match multiple conditions in one case statement in Bash.

2. Matching a Single Condition

The typical behavior of a case statement in Bash is to match only one condition and execute its corresponding set of commands. However, in modern versions of Bash, a case statement has the ability to match many conditions. Whether one or more conditions can be matched is determined by the choice of a terminator.

The ;; terminator tells Bash to exit the case statement when the current case option matches the variable, or to continue evaluating the next case option if there is no match.

The ;; terminator is the usual one for case statements in Bash:

$ cat script.sh
#!/usr/bin/env bash
var=abc
case $var in
    *a*) echo "Level 1" ;;
    *b*) echo "Level 2" ;;
    *c*) echo "Level 3" ;;
esac

Once the program encounters the first case condition and it evaluates to true, the associated command is executed. The program then terminates the case statement without following through to the second and third case options. Consequently, the program executes only the command associated with the first case option:

$ chmod u+x script.sh
$ ./script.sh
Level 1

We see that the case statement terminates after the first match without evaluating any additional patterns.

3. Matching Multiple Conditions

Since version 4.0 of Bash, case statements support matching more than one condition. The ;;& terminator instructs Bash to continue evaluating the next case option regardless of whether the current one is a match or not.

If we wish to match more than one condition in a case statement, we use the ;;& terminator:

$ cat script.sh
#!/usr/bin/env bash
var=abc
case $var in
    *a*) echo "Level 1" ;;&
    *b*) echo "Level 2" ;;&
    *c*) echo "Level 3" ;;
esac

In this case, when the variable matches the first case option, the program executes the associated command and proceeds to evaluate the next case option because of the ;;& terminator. The program finds that the second case option also matches, executes its command, and evaluates the third case option due to the ;;& terminator of the second case option. The program then executes the command associated with the third case option because it also matches the variable:

$ chmod u+x script.sh
$ ./script.sh
Level 1
Level 2
Level 3

We see that the program executes all three commands because the variable matches all three patterns of the different case options.

If the ;;& terminator appears only for the first case option, then the result would be different:

$ cat script.sh
#!/usr/bin/env bash
var=abc
case $var in
    *a*) echo "Level 1" ;;&
    *b*) echo "Level 2" ;;
    *c*) echo "Level 3" ;;
esac

Here, when the program matches the first condition, but evaluates the second condition and discovers that it also matches. The program doesn’t evaluate the third case option because the second case option is a match and terminates with a double semicolon:

$ chmod u+x script.sh
$ ./script.sh
Level 1
Level 2

Running the script, we obtain an output only for the first and second case options.

4. case Statements With Fallthrough

It’s worth noting that there is another type of terminator for case statements in Bash, namely the ;& terminator. This type of terminator allows for fallthrough. That is, when the program matches the variable with a particular case option, it executes not only the corresponding set of commands but also the commands of the next case option, regardless of whether that case option matches the variable or not.

Let’s use this type of terminator with the first case option:

$ cat script.sh
#!/usr/bin/env bash
var=a
case $var in
    *a*) echo "Level 1" ;&
    *b*) echo "Level 2" ;;
    *c*) echo "Level 3" ;;
esac

In this example, upon finding a match with the first pattern, the program executes the associated command along with the command of the second case option, even though the pattern in the second case option doesn’t match the variable:

$ chmod u+x script.sh
$ ./script.sh
Level 1
Level 2

The result shows that the script executes the commands of both the first and second case options.

5. Conclusion

In this article, we’ve seen that a case statement in Bash is used to execute different sets of commands based on the value of a variable. Further, if we change the terminators, we modify the behavior. By using the ;;& terminator, we can match multiple conditions in a single case statement.

Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.