How to Run Regular Expressions Inside a Case Statement in Bash

Abdullah Bukhari Feb 02, 2024
  1. Introduction to Regular Expressions
  2. The Need to Enable Complex String Matching in Bash
  3. String Matching Using Regex in a Case Structure
  4. String Matching Using Regex in an If-Else Structure
How to Run Regular Expressions Inside a Case Statement in Bash

This article explores regular expressions, their basic syntax, and how to run them with a case structure and an if-else structure in Bash.

Introduction to Regular Expressions

Regular expressions, also known as regex or regexp, are a sequence of characters used for text/string matching. The regex can be very powerful and will save a lot of time when you need to parse tons of data.

Although Bash doesn’t use regex, it uses string matching, whose syntax is similar to regex. The below script will help you get comfortable with the basics of string matching with Bash.

?(a pattern list)
# Matches exactly zero or one instance of the pattern

*(a pattern list)
# This matches zero or more instances of the pattern.

+(a pattern list)
# This matches one or more instances of the pattern.

@(a pattern list)
# This matches one of the enclosed patterns.

!(a pattern list)
# This matches any pattern except the one enclosed.

The above code fence showcases the basic regex syntax; if you want to read more about regex, visit this link.

The Need to Enable Complex String Matching in Bash

By default, you can run simple regular expressions in Bash; complicated regular expressions will require you to enable an option of extglob. The below commands will show you how to enable or disable extglob to allow you to run complicated regular expressions.

shopt -s extglob # this command enables extglob and allows the execution of complicated regex
shopt -u extglob # this command disables extglob and disables execution of complicated regex

The extglob in the command above stands for extended globing. If set, the complex/advanced pattern matching features given under pathname expansion are permitted.

It must be noted that it is impossible to know whether a regular expression is complicated without running it. Enable the extglob option to spare yourself any misery and run all your commands worry-free.

One question you might have is how we will know if the extglob is on or off. See the below command for reference.

shopt | grep extglob # displays status of extglob

Output:

extglob off # displays this line if extglob is disabled
extglob on # displays this line if extglob is enabled

enabling complex string matching in bash

The above command will display the status of the extglob, whether on or off.

String Matching Using Regex in a Case Structure

String matching (similar to regex) can be made even more powerful with a case structure, which we would want to use to allow ourselves to parse more complicated data. The below commands will work you through the use of case in Bash.

case EXPRESSION in
Match_1)
STATEMENTS # run this statement if in matches match_1
;;
Match_2)
STATEMENTS # run this statement if in matches match_2
;;
Match_N)
STATEMENTS # run this statement if in matches match_N
;;
*)
STATEMENTS # otherwise, run this statement
;;
Esac # signals the end of the case statement to the kernel

The above code is the generic syntax you will use in case you want to combine Bash string matching with a case structure.

Bash, by default, allows simple pattern matching. For example, it will successfully execute the below Bash command.

cat sh*
# the above command displays the contents of all files whose name begins #with sh to the monitor (or stdout)

However, given the below command (which uses complicated pattern matching), you’ll get an error bash: syntax error near unexpected token '('.

cat +([0-9]) # this command displays contents of files whose names are
# entirely composed of numbers

error when extglob disabled

If you want to dive further into string matching in Bash, then use the below command.

man bash # man is a short form of manual pages here

The manual pages are a utility that can be used to find information on any Bash command, system call, and much more.

If you’re using string matching with a case in Bash, it is a good practice first to declare and define a variable you’ll be comparing the pattern.

We used a case with string matching in the below commands snippet. Notice how we’ve used the basics of string matching to generate a powerful string-matching algorithm.

Let’s look at the commands.

# Remember to not forget to enable extglob
shopt -s extglob # enables extglob
shopt | grep extglob # checks if extglob is enabled

some_variable="rs-123.host.com"; # declare and define variable
case $some_variable in
ab-+([0-9])\.host\.com) echo "First 2 characters were ab"
;;
ks-+([0-9])\.host\.com) echo "First 2 characters were ks"
;;
cs-+([0-9])\.host\.com) echo "First 2 characters were cs"
;;
*)echo "unknown first 2 characters"
;;
esac;
# the above command will display the unknown first 2 characters as we
# don't have a match in the first three cases, so the last default one will #automatically be true

Output:

unknown first 2 characters

If you analyze the above string matching command, if the first two characters are one of (ab, ks, cs) and the next character is a hyphen () followed by any number of digits and ending with .host.com, one of the first three cases will be successful, and an appropriate message will be displayed.

However, if this is not the case, then the default (i.e., the otherwise case) will run, and we will get a message: unknown first 2 characters.

We have a simpler solution if you find the above commands too complicated. The below command explains just exactly how.

some_variable="rs-123.host.com"; # declare and define variable
case $some_variable in
ab*.host.com) echo "First 2 characters were ab"
;;
# the command below stays the same

string matching using regex

The above command does the same as the more complicated case structure we used above.

String Matching Using Regex in an If-Else Structure

Another way to code powerful string-matching algorithms is to use them with an if-else structure. We would want to use this to parse more complicated data.

The following Bash command walks you through the syntax of an if-else structure.

if expression1
then
task1
elif expression2
then
task2
else
task3
fi # signals ending of if else structure

Working the if-else structure is easy; first, we evaluate the first expression.

If it’s true, we execute task 1. Else, we consider the second expression.

If it is true, then execute task 2. Execute task3 otherwise.

Now that you’re comfortable with the syntax of an if-else structure let’s replicate the command used in the case structure to an equivalent if-else structure. Consult the command below to do that.

# Remember to not forget to enable extglob
shopt -s extglob # enables extglob
shopt | grep extglob # checks if extglob is enabled

some_variable="rs-123.host.com"; # declare and define variable
if expr "$some_variable" : ‘ab-+([0-9])\.host\.com’ >/dev/null; then echo "First 2 characters were ab"
elif expr "$some_variable" : ‘ks-+([0-9])\.host\.com’ >/dev/null; then echo "First 2 characters were ks"
elif expr "$some_variable" : ‘cs-+([0-9])\.host\.com’ >/dev/null; then echo "First 2 characters were cs"
else echo "unknown first 2 characters"
fi

# the above command will display the unknown first 2 characters as we
# don't have a match in the first three cases, so the last default one will #automatically be true

Output:

unknown first 2 characters

string matching using regex in an if else

The above command is the if-else equivalent of the case structure we used earlier.

Related Article - Bash Regex