IF 语句中的 Linux Bash OR 运算符未按预期工作

Wol*_*olf 2 bash shell-script

假设有 2 台具有不同命名约定的主机......

ab_01ab_cd

我想确保他们的命名约定符合某些标准。

所以,我写了一个简单的脚本来测试它。

wolf@linux:~$ host='ab_01'

wolf@linux:~$ if [[ $host =~ [a-z][a-z]_[a-z][a-z] ]]; then echo True; else echo False; fi
False

wolf@linux:~$ if [[ $host =~ [a-z][a-z]_[0-9][0-9] ]]; then echo True; else echo False; fi
True
Run Code Online (Sandbox Code Playgroud)

有用!

下一步是将这两个正则表达式与 Shell 中的 OR 运算符结合起来,即 ||

if [[ $host =~ [a-z][a-z]_[a-z][a-z] || $host =~ [a-z][a-z]_[0-9][0-9] ]];
then
    echo True
else
    echo False
fi
Run Code Online (Sandbox Code Playgroud)

让我们测试一下

wolf@linux:~$ echo $host
ab_01
wolf@linux:~$ if [[ $host =~ [a-z][a-z]_[a-z][a-z] || $host =~ [a-z][a-z]_[0-9][0-9] ]];
> then
>     echo True
> else
>     echo False
> fi
True
wolf@linux:~$
Run Code Online (Sandbox Code Playgroud)

它适用于ab_01ab_cd

但是,当我向主机名添加更多字符时,当它应该是 False 时,我仍然会得到 True。

让我们用host='ab_0123'和测试这个host='ab_cdef'

wolf@linux:~$ host='ab_0123'
wolf@linux:~$ if [[ $host =~ [a-z][a-z]_[a-z][a-z] || $host =~ [a-z][a-z]_[0-9][0-9] ]];
> then
>     echo True
> else
>     echo False
> fi
True
wolf@linux:~$ 
Run Code Online (Sandbox Code Playgroud)

另一个测试也显示 True 而不是 False

wolf@linux:~$ host='ab_cdef'
wolf@linux:~$ if [[ $host =~ [a-z][a-z]_[a-z][a-z] || $host =~ [a-z][a-z]_[0-9][0-9] ]];
> then
>     echo True
> else
>     echo False
> fi
True
wolf@linux:~$ 
Run Code Online (Sandbox Code Playgroud)

这段代码有什么问题以及如何解决?

ilk*_*chu 5

与模式匹配不同,正则表达式匹配不锚定到字符串的开头/结尾,因此字符串中任何地方的匹配就足够了。(它更像是“搜索”而不是“匹配”,我认为某些 Python 函数名称可以区分。)ab_cdef包含ab_cd匹配。

您必须使用^和明确锚定模式$

$ if [[ foobar =~ o ]]; then echo yes; else echo no; fi
yes
$ if [[ foobar =~ ^o$ ]]; then echo yes; else echo no; fi
no
Run Code Online (Sandbox Code Playgroud)

而不是||你也可以把交替的正则表达式中:

re='^[a-z][a-z]_([0-9][0-9]|[a-z][a-z])$'
if [[ $host =~ $re ]]; then ...
Run Code Online (Sandbox Code Playgroud)

(或者对于一个宽松的正则表达式,允许ab_a0: ^[a-z][a-z]_[0-9a-z][0-9a-z]$.)