Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to do an OR in a bash regular expression?

Tags:

regex

grep

bash

I know I can use grep, awk etc, but I have a large set of bash scripts that have some conditional statements using =~ like this:

#works
if [[ "bar" =~ "bar" ]]; then echo "match"; fi

If I try and get it to do a logical OR, I can't get it to match:

#doesn't work
if [[ "bar" =~ "foo|bar" ]]; then echo "match"; fi

or perhaps this...

#doesn't work
if [[ "bar" =~ "foo\|bar" ]]; then echo "match"; fi

Is it possible to get a logical OR using =~ or should I switch to grep?

like image 826
simon Avatar asked Jun 04 '19 18:06

simon


People also ask

Can you use regular expressions in bash?

Since version 3 (circa 2004), bash has a built-in regular expression comparison operator, represented by =~. A lot of scripting tricks that use grep or sed can now be handled by bash expressions and the bash expressions might just give you scripts that are easier to read and maintain.

Can you do an OR in regex?

Alternation is the term in regular expression that is actually a simple “OR”. In a regular expression it is denoted with a vertical line character | . For instance, we need to find programming languages: HTML, PHP, Java or JavaScript.

What is $_ in bash?

$_ (dollar underscore) is another special bash parameter and used to reference the absolute file name of the shell or bash script which is being executed as specified in the argument list. This bash parameter is also used to hold the name of mail file while checking emails.

What does =~ mean in bash?

A regular expression matching sign, the =~ operator, is used to identify regular expressions.


Video Answer


1 Answers

You don't need a regex operator to do an alternate match. The [[ extended test operator allows extended pattern matching options using which you can just do below. The +(pattern-list) provides a way to match one more number of patterns separated by |

[[ bar == +(foo|bar) ]] && echo match

The extended glob rules are automatically applied when the [[ keyword is used with the == operator.

As far as the regex part, with any command supporting ERE library, alternation can be just done with | construct as

[[ bar =~ foo|bar ]] && echo ok
[[ bar =~ ^(foo|bar)$ ]] && echo ok

As far why your regex within quotes don't work is because regex parsing in bash has changed between releases 3.1 and 3.2. Before 3.2 it was safe to wrap your regex pattern in quotes but this has changed in 3.2. Since then, regex should always be unquoted.

You should protect any special characters by escaping it using a backslash. The best way to always be compatible is to put your regex in a variable and expand that variable in [[ without quotes. Also see Chet Ramey's Bash FAQ, section E14 which explains very well about this quoting behavior.

like image 77
Inian Avatar answered Nov 10 '22 00:11

Inian