如何在bash脚本中使用正则表达式否定测试?

时间:2010-12-27 23:53:48

标签: regex bash conditional negate

使用GNU bash(版本4.0.35(1)-release(x86_64-suse-linux-gnu),我想用正则表达式否定测试。例如,我想有条件地添加一个路径到PATH变量,如果路径不存在,如:

TEMP=/mnt/silo/bin
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/Scripts:
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/local/bin
if [[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH; else PATH=$PATH:$TEMP; fi
export PATH

我确信有一百万种方法可以做到这一点,但我想知道的是,条件是否可以以某种方式被否定,如(错误的):

TEMP=/mnt/silo/bin
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/Scripts:
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
TEMP=/mnt/silo/local/bin
if ![[ ${PATH} =~ ${TEMP} ]] ; then PATH=$PATH:$TEMP; fi
export PATH

5 个答案:

答案 0 :(得分:145)

你做对了,只需在![[之间加一个空格,如if ! [[

答案 1 :(得分:101)

您也可以将感叹号放在括号内:

if [[ ! $PATH =~ $temp ]]

但你应该锚定你的模式以减少误报:

temp=/mnt/silo/bin
pattern="(^|:)$temp(:|$)"
if [[ ! $PATH =~ $pattern ]]

在开头或结尾处使用冒号(或两者)之前或之后查找匹配。我建议使用小写或混合大小写变量名作为习惯,以减少名称与shell变量冲突的可能性。

答案 2 :(得分:17)

最安全的方法就是放!正如[[ ]]中的正则表达式否定一样:

if [[ ! ${STR} =~ YOUR_REGEX ]]; then

否则在某些系统上可能会失败。

答案 3 :(得分:7)

是的,你可以否定SiegeX已经指出的测试。

但是,您不应该使用正则表达式 - 如果您的路径包含特殊字符,它可能会失败。试试这个:

[[ ":$PATH:" != *":$1:"* ]]

(Source)

答案 4 :(得分:4)

在这种情况下,我喜欢简化代码而不使用条件运算符:

TEMP=/mnt/silo/bin
[[ ${PATH} =~ ${TEMP} ]] || PATH=$PATH:$TEMP