APLawrence.com -  Resources for Unix and Linux Systems, Bloggers and the self-employed


Bash in-process regular expressions

September 2005

Bash acquired in-process regular expressions in version 3.0, but I never noticed, probably because most of the machines I'm using are Bash 2.05b. As I'm not necessarily in a position to upgrade any old box I happen to be working on, I tend to stick to the stuff that will work anywhere, which often means piping out to grep for a regular expression test.

However, should you have an environment where you can depend on this feature being present, in-process regexes obviously avoid firing up another process for grep and are much more neat to write or read.

The syntax is Perlish, using "=~". You also have access to sub-matches: $BASH_REMATCH is the string matched, ${BASH_REMATCH[1]} is the first parenthesided match, and so on. So, we can do:


if [[ "$input" =~ 'foo(.*)' ]]
then
        echo $BASH_REMATCH is what I wanted   
        echo but just ${BASH_REMATCH[1]}
fi
 

and other more interesting tasks.

Note discussion of quotes in the comments!

Set 'nocaseglob' for case insensitivity. The return value for these is 0 for a match, 1 for no match, and (how thoughtful) 2 if the expression is syntactically incorrect, so watch out for the other side of that "if" - a non-zero return might mean you screwed up your pattern.





(OLDER)    <- More Stuff -> (NEWER)    (NEWEST)   

Printer Friendly Version

-> -> Bash in-process regular expressions

8 comments




More Articles by

Find me on Google+

© Tony Lawrence







Mon Aug 4 05:18:06 2008: 4465   Taco


When trying this, I could only get it to work without the single quotes:

 
if [[ $input =~ foo(.*) ]]
then
echo $BASH_REMATCH is what I wanted
echo but just ${BASH_REMATCH[1]}
fi




Sat Jul 18 15:57:55 2009: 6644   anonymous

gravatar
me too, single or double quotes don't work... strange syntax...



Mon Mar 29 10:54:01 2010: 8294   vayerx

gravatar


Any part of the pattern may be quoted to force it to be matched as a string.



Sun Aug 8 02:25:43 2010: 8878   VertigoRay

gravatar


Worked for me as it was shown in the article ...
$ uname -srvo
Linux 2.6.32.8-grsec-2.1.14-modsign-xeon-64 #2 SMP Sat Mar 13 00:42:43 PST 2010 GNU/Linux

Thanks for the post. Really helped me out.



Mon Sep 27 13:17:09 2010: 9012   JonathanCross

gravatar


I must use unquoted regex as well.

$ if [[ sam =~ ^bob|sam$ ]];then echo match;else echo NO match;fi
match
$ if [[ sam2 =~ ^bob|sam$ ]];then echo match;else echo NO match;fi
NO match

$ bash --version
GNU bash, version 3.2.39(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2007 Free Software Foundation, Inc.






Mon Jun 9 14:57:12 2014: 12480   Rei

gravatar


Thx !

And for invert match:
if ! [[ "$input" =~ 'foo(.*)' ]]
then
echo $BASH_REMATCH is what I wanted
echo but just ${BASH_REMATCH[1]}
fi

Some !~ operator doesn't work.



Sat Feb 21 10:36:53 2015: 12613   7d42)

gravatar


@TonyLawrence
As others have noted, the regex pattern should not be quoted. If quotes are literally part of the match, then they should be escaped with a backslash. Quotes can be used to match a string, but in that case why bother using regex?

Ideally the example would begin as follows:
[[ $input =~ foo(.*) ]]

Note that the left side does not need to be quoted here (word splitting and pathname expansion are not performed for [[ expressions).

@JonathanCross
You used the example [[ sam =~ ^bob|sam$ ]]. This will match strings starting with bob (i.e. bobby) and/or ending with sam (i.e. rossam). You probably want this: [[ sam =~ ^(bob|sam)$ ]]



Sat Feb 21 11:41:01 2015: 12614   TonyLawrence

gravatar


Well, as you can see from the comments, other people found quotes worked. I can assure you that they did when I wrote this, but today on the same machines, it does not - of course Bash has been upgraded more than once since then - it's been almost ten years!


------------------------
Kerio Samepage


Have you tried Searching this site?

Unix/Linux/Mac OS X support by phone, email or on-site: Support Rates

This is a Unix/Linux resource website. It contains technical articles about Unix, Linux and general computing related subjects, opinion, news, help files, how-to's, tutorials and more.

Contact us





It is the the duty of a Webmaster to allocate URIs which you will be able to stand by in 2 years, in 20 years, in 200 years. (Tim Berners-Lee)





This post tagged: