How to Run Regular Expressions Inside a Case Statement in Bash
- Introduction to Regular Expressions
- The Need to Enable Complex String Matching in Bash
-
String Matching Using Regex in a
Case
Structure -
String Matching Using Regex in an
If-Else
Structure
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
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
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
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
The above command is the if-else
equivalent of the case
structure we used earlier.