regex match in Bash if statement doesn't work

后端 未结 2 1132
面向向阳花
面向向阳花 2021-01-18 09:59

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

相关标签:
2条回答
  • 2021-01-18 10:27

    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
    
    0 讨论(0)
  • 2021-01-18 10:33

    There are a multiple things to fix here

    • bash supports regex pattern matching within its [[ extended test operator and not within its POSIX standard [ test operator
    • Never quote our regex match string. bash 3.2 introduced a compatibility option compat31 (under New Features in Bash 1.l) which reverts bash regular expression quoting behavior back to 3.1 which supported quoting of the regex string.
    • Fix the regex to use [[:space:]] instead of just [:space:]

    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.

    0 讨论(0)
提交回复
热议问题