Many people think that RegExp is alien to Bash/KSH Scripting and depends on GREP or SED to use regexp extensively. But from Version 3 of Bash we can use a regular expression without using grep or sed. This will save us a lot of time and reduce the number of lines of a script we write.
Let us take some example; I want to ask a user to enter “Yes” to do some activity depending on his input. He may end up with entering YES or Yes or YEs or some other form of YES or even just Y or y.
Earlier versions of BASH and KSH we have to depend on grep to put a check on user’s different inputs as shown below code.
read option1
echo $option1 | grep -E ‘[Yy][Ee][Ss]|[Yy]’
if [[ “$?” -eq 0 ]]
then
echo “Do some thing.”
else
echo “Do another thing.”
fi
output:
Do Something
If you see above code we are using three commands(echo, grep and if statement) to accomplish our task.
Which will use system resources a bit more when we can accomplish with a just BASH/KSH alone.
From BASH version 3 there is an inbuilt regex operator( =~ ) which will help us to solve this problem
If you are new to regular expressions, please click here
Below are the types of regular expressions we have and we will go with each and every regexp with an example.
Basic Regular Expressions
^ –Caret symbol, Match beginning of the line/Variable.
$ –Match End of the line/variable.
. –Match Any single character.
* — Match 0 or more occurrence of a previous character(This is a bit tricky).
[] – Match Range of characters, just single occurrence.
[a-z] –Match small letters
[A-Z] –Match cap letters
[0-9] – Match numerical.
[^] – Match Negate a sequence of char followed by ^.
— Match Escape character, for matching special chars like ., * etc.
Extended Regular Expressions
{n} –Match number of occurrence of a character
{n,m} –Match a character which is repeated n to m times.
{n,} –Match a repeated character which is repeated n or more times.
+ –Match one or more occurrences of previous character.
? – Match 0 or 1 occurrence of previous character.
— Match Either character
() –match a group of characters
Let us start with an example
I have a variable var1 whose value is “abbbcd acdef 123 acd cda2”. And we are going to use the same variable for below examples.
Example1: Check var1 start with “an” or not
if [[ “$var1” =~ ^a ]]
then
echo “Yes, it start with a”
else
echo “It does not start with a”
fi
Output:
Yes, it start with a
Note: Don’t give quotes around regexp, Your bash/ksh will take care of that.
Example2: Check if var1 ends with 2 or not
if [[ “$var1” =~ 2$ ]]
then
echo “Yes, it’s end with 2”
else
echo “It does not end with 2”
fi
Output:
Yes, it end with 2
Example3: Check if var1 have a string which starts with a and ends with d and should contain only one letter between them.
if [[ “$var1” =~ a.d ]]
then
echo “Yes, it’s present.”
else
echo “It not there.”
fi
Output:
Yes, it’s present
Example4: Check if var1 have a string which may contain’s 0 or more times of b
if [[ “$var1” =~ b* ]]
then
echo “Yes, it’s true.”
else
echo “It not there.”
fi
Output:
Yes, it’s true.
Note: The output of this script is always true because it we can have var1 with b’s and without b’s. We have to depend on + for a meaning full checking like at-least 1 b occurrence.
Example5: Check if var1 contain contains either abc or adc word in it.
if [[ “$var1” =~ a[bd]c ]]
then
echo “Yes, it’s present.”
else
echo “It not there.”
fi
Output:
Yes, it’s present
This will match either abc or adc and gives the output as it present.
Example6: Check if var1 contains abc or bbc or cbc or dbc to zbc
if [[ “$var1” =~ [a-z]bc ]]
then
echo “Yes, it’s present”
else
echo “It not there”
fi
Output:
Yes, it’s present
I will leave [A-Z] and [0-9] option to reader it self. Explore your self on this.
Example7: Check if var1 do not contain z in it
if [[ “$var1” =~ [^z] ]]
then
echo “Its not there”
else
echo “z is present”
fi
Output:
Its not there
Example8: Check if a string “123 acd” is present in var1 or not
if [[ “$var1” =~ 123 acd ]]
then
echo “Yes, it’s present”
else
echo “it’s not present”
fi
Note: If you observe regexp, We did not used quotes, your bash/ksh will take care of it.
Output:
Yes, it’s present.
Example9: Check if var1 contain a string which have 2 b’s in between a and cd.
if [[ “$var1” =~ ab{2}cd ]]
then
echo “Yes, it’s present”
else
echo “it’s not present”
fi
the output will be “Its not present” because our var1 variable(abbbcd acdef 123 acd cda2) have 3 b’s between a nd cd.
Example10: Check if var1 contain a string which have 2 or 3 b’s between a and cd.
if [[ “$var1” =~ ab{2,3}cd ]]
then
echo “Yes, it’s present”
else
echo “it’s not present”
fi
The output will be “Yes, Its present”, because it try to match abbbcd in the string, if one matches.
Example11: Check if var1 contain a string which have 2 or more b’s between a and cd.
if [[ “$var1” =~ ab{2,}cd ]]
then
echo “Yes, it’s present”
else
echo “it’s not present”
fi
Output:
Yes, it’s present
Example12: Check if var1 contain 1 or more b’s between a and cd
if [[ “$var1” =~ ab+cd ]]
then
echo “Yes, it’s present”
else
echo “it’s not present”
fi
Output:
Yes, it’s present
Example13: Check if var1 contain 0 or 1 b between a and cd
if [[ “$var1” =~ ab?cd ]]
then
echo “Yes, it’s present”
else
echo “it’s not present”
fi
Output:
Yes, it’s present
Example14: Check if var1 contain either acdef or acd in it?
if [[ “$var1” =~ acdef|acd ]]
then
echo “Yes, it’s present”
else
echo “it’s not present”
fi
If either one of acdef or acd is there, if loop will be true.
Example15: Check if var1 contain abbbcd or acd in it. We can combain the letters which are common in both the words with () and
if [[ “$var1” =~ a(bbbc|c)d ]]
then
echo “Yes, it’s present”
else
echo “it’s not present”
fi
Output:
Yes, it’s present
if you want to make this more simple you can write the above regexp as below.
if [[ “$var1” =~ a(bbb|)cd ]]
then
echo “Yes, it’s present”
else
echo “it’s not present”
fi
Now come back to our old code on getting user input of Yes without using echo and grep commands..
echo $result | grep -E ‘[Yy][Ee][Ss]|[Yy]’
if [[ “$?” -eq 0 ]]
then
echo “Do some thing”
else
echo “Do another thing”
fi
The above code can be written as
if [[ “$var1” =~ ([Yy]|([Ee][Ss])) ]]
then
echo “Yes, it’s present”
else
echo “it’s not present”
fi
So that user can type Y or y or yes or Yes or YEs or YES or YeS or yEs or yES or yeS. All these things will be matched.
Keep visiting us to get more update on Shell scripting.
Latest posts by Surendra Anne (see all)
- Docker: How to copy files to/from docker container - June 30, 2020
- Anisble: ERROR! unexpected parameter type in action:
Fix - June 29, 2020 - FREE: JOIN OUR DEVOPS TELEGRAM GROUPS - August 2, 2019
- Review: Whizlabs Practice Tests for AWS Certified Solutions Architect Professional (CSAP) - August 27, 2018
- How to use ohai/chef-shell to get node attributes - July 19, 2018