dig_123
dig_123

Reputation: 2358

Regex stored in a shell variable doesn't work between double brackets

The below is a small part of a bigger script I'm working on, but the below is giving me a lot of pain which causes a part of the bigger script to not function properly. The intention is to check if the variable has a string value matching red hat or Red Hat. If it is, then change the variable name to redhat. But it doesn't quite match the regex I've used.

getos="red hat"
rh_reg="[rR]ed[:space:].*[Hh]at"
if [ "$getos" =~ "$rh_reg" ]; then
  getos="redhat"
fi
echo $getos

Any help will be greatly appreciated.

Upvotes: 7

Views: 1913

Answers (2)

Inian
Inian

Reputation: 85580

There are a multiple things to fix here

So just do

getos="red hat"
rh_reg="[rR]ed[[:space:]]*[Hh]at"
if [[ "$getos" =~ $rh_reg ]]; then 
    getos="redhat"
fi;

echo "$getos"

or enable the compat31 option from the extended shell option

shopt -s compat31
getos="red hat"
rh_reg="[rR]ed[[:space:]]*[Hh]at"
if [[ "$getos" =~ "$rh_reg" ]]; then 
    getos="redhat"
fi
echo "$getos"
shopt -u compat31

But instead of messing with those shell options just use the extended test operator [[ with an unquoted regex string variable.

Upvotes: 9

John1024
John1024

Reputation: 113834

There are two issues:

First, replace:

rh_reg="[rR]ed[:space:].*[Hh]at"

With:

rh_reg="[rR]ed[[:space:]]*[Hh]at"

A character class like [:space:] only works when it is in square brackets. Also, it appears that you wanted to match zero or more spaces and that is [[:space:]]* not [[:space:]].*. The latter would match a space followed by zero or more of anything at all.

Second, replace:

[ "$getos" =~ "$rh_reg" ]

With:

[[ "$getos" =~ $rh_reg ]]

Regex matches requires bash's extended test: [[...]]. The POSIX standard test, [...], does not have the feature. Also, in bash, regular expressions only work if they are unquoted.

Examples:

$ rh_reg='[rR]ed[[:space:]]*[Hh]at'
$ getos="red Hat"; [[ "$getos" =~ $rh_reg ]] && getos="redhat"; echo $getos
redhat
$ getos="RedHat"; [[ "$getos" =~ $rh_reg ]] && getos="redhat"; echo $getos
redhat

Upvotes: 4

Related Questions