Bash Regular Expressions
May 26th, 2008 by Mitch Frazier in
When working with regular expressions in a shell script the norm is to use grep or sed or some other external command/program. Since version 3 of bash (released in 2004) there is another option: bash's built-in regular expression comparison operator "=~".
Bash's regular expression comparison operator takes a string on the left and an extended regular expression on the right. It returns 0 (success) if the regular expression matches the string, otherwise it returns 1 (failure).
In addition to doing simple matching, bash regular expressions support sub-patterns surrounded by parenthesis for capturing parts of the match. The matches are assigned to an array variable BASH_REMATCH. The entire match is assigned to BASH_REMATCH[0], the first sub-pattern is assigned to BASH_REMATCH[1], etc..
The following example script takes a regular expression as its first argument and one or more strings to match against. It then cycles through the strings and outputs the results of the match process:
#!/bin.bash
if [[ $# -lt 2 ]]; then
echo "Usage: $0 PATTERN STRINGS..."
exit 1
fi
regex=$1
shift
echo "regex: $regex"
echo
while [[ $1 ]]
do
if [[ $1 =~ $regex ]]; then
echo "$1 matches"
i=1
n=${#BASH_REMATCH[*]}
while [[ $i -lt $n ]]
do
echo " capture[$i]: ${BASH_REMATCH[$i]}"
let i++
done
else
echo "$1 does not match"
fi
shift
done
Assuming the script is saved in "bashre.sh", the following sample shows its output:
# sh bashre.sh 'aa(b{2,3}[xyz])cc' aabbxcc aabbcc
regex: aa(b{2,3}[xyz])cc
aabbxcc matches
capture[1]: bbx
aabbcc does not match
__________________________
Mitch Frazier is the System Administrator at Linux Journal.
Special Magazine Offer -- 2 Free Trial Issues!
Receive 2 free trial issues of Linux Journal as well as instant online access to current and past issues. There's NO RISK and NO OBLIGATION to buy. CLICK HERE for offer
Linux Journal: delivering readers the advice and inspiration they need to get the most out of their Linux systems since 1994.
Sorry, offer available in the US only. International orders, click here.
Subscribe now!
The Latest
Featured Videos
The X Window System is a magnificent platform for many uses, but using it to run an application over a slow network is nearly impossible. This is an introduction to NX, a technology that makes remote applications fly even over commodity internet.
Linux Journal Gadget Guy, Shawn Powers, reviews the Flip Video Ultra, a small portable video camera, and shows us how easy it is to edit the video with Kino.
Thanks to our sponsor: Silicon Mechanics
Recently Popular
From the Magazine
September 2008, #173
Feeling a bit like a Thermian? Never give up, never surrender! Someday, you could go from underdog to top dog. Just take a look at a few of the underdogs we highlight in this issue: Mutt, djbdns, Nginix, Gentoo, Xara and the program voted mostly likely to fail just a few years back—Firefox. If Firefox not radical enough for you, check out Chef Marcel's column for some more alternatives. Having trouble mapping your program data to your relational database? If so, Rueven Lerner shows you some tricks in his At The Forge column.
Need to run GUI applications on your server in the next state? In his Paranoid Penguin column, Mick Bauer shows you how to do it securely. Kyle Rankin keeps hacking and slashing and shows you a few split screen secrets you may not be familiar with. Finally, we all know what happens next February, but only Doc knows what happens afterward.
Delicious
Digg
Reddit
Newsvine
Technorati







add color and better indentation to the output
On July 7th, 2008 Albert Bicchi (not verified) says:
#!/bin/sh if [[ $# -lt 2 ]]; then echo "Usage: regex PATTERN STRINGS..." exit 1 fi regex=$1 shift echo "regex: $regex" echo while [[ $1 ]] do if [[ $1 =~ $regex ]]; then echo -e "\t\E[42;37m${1} - matches\E[33;0m" i=1 n=${#BASH_REMATCH[*]} while [[ $i -lt $n ]] do echo -e "\t\t\E[43;37mcapture[$i]: ${BASH_REMATCH[$i]}\E[33;0m" let i++ done else echo -e "\t\E[41;37m${1} - does not match\E[33;0m" fi shift doneIs "(( $# < 2 ))" an
On June 25th, 2008 Anonymous (not verified) says:
Is "(( $# < 2 ))" an alternative conditional expression for the line "[[ $# -lt 2 ]]"?
Could you discuss BASH expressions with [[]] (()) and their valid operators. It seems the -lt, -gt, -a,
etc, can be replaced with <, >, &&, etc, if used with (()) --- replacing [] with (()) (numeric) and [[]] (strings).
Thank you.
PS: The captcha is really hard to read. It would be nice it there was an option to generate a new one that could possible be read by a mere human.
Is "(( $# < 2 ))" an
On June 25th, 2008 Anonymous (not verified) says:
Is "(( $# < 2 ))" an alternative conditional expression for the line "[[ $# -lt 2 ]]"?
Could you discuss BASH expressions with [[]] (()) and their valid operators. It seems the -lt, -gt, -a,
etc, can be replaced with <, >, &&, etc, if used with (()) --- replacing [] with (()) (numeric) and [[]] (strings).
Thank you.
Wow, this may be a bit much....
On June 7th, 2008 Image Hosting (not verified) says:
I'm in "learning mode" and I just came across this blog, which is great, but it appears that I have quite a bit to learn. Why didn't I start this several years ago!?!
Image Hosting
That simple?!
On May 28th, 2008 Robert de Bock (not verified) says:
My god, Bash sure is a great tool! Thanks for the information.