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

时间:2022-01-28 16:23:27

Using GNU bash (version 4.0.35(1)-release (x86_64-suse-linux-gnu), I would like to negate a test with Regular Expressions. For example, I would like to conditionally add a path to the PATH variable, if the path is not already there, as in:

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

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

I'm sure there are a million ways to do this, but what I would like to know is if the conditional can be negated somehow, as in (the erroneous):

我确信有无数种方法可以做到这一点,但我想知道的是,如果条件句可以被否定,比如(错误的):

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

Thanks!

谢谢!

5 个解决方案

#1


115  

You had it right, just put a space between the ! and the [[ like if ! [[

你说对了,在这之间留点空间!还有那个。[[

#2


88  

You can also put the exclamation point inside the brackets:

你亦可在括号内加上感叹号:

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

but you should anchor your pattern to reduce false positives:

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

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

which looks for a match at the beginning or end with a colon before or after it (or both). I recommend using lowercase or mixed case variable names as a habit to reduce the chance of name collisions with shell variables.

它在开始或结束时查找匹配,并在其之前或之后使用冒号(或两者都使用)。我建议使用小写或混合的case变量名作为一个习惯,以减少与shell变量发生名称冲突的机会。

#3


16  

the safest way is to put the ! for the regex negation within the [[ ]] like this:

最安全的方法是把!对于[]内的regex否定,如下:

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

otherwise it might fail on certain systems.

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

#4


6  

Yes you can negate the test as SiegeX has already pointed out.

是的,正如西格克斯已经指出的那样,你可以否定这个测试。

However you shouldn't use regular expressions for this - it can fail if your path contains special characters. Try this instead:

但是,如果您的路径包含特殊字符,则不能使用正则表达式。试试这个:

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

(Source)

(源)

#5


2  

I like to simplify the code without using conditional operators in such cases:

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

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

#1


115  

You had it right, just put a space between the ! and the [[ like if ! [[

你说对了,在这之间留点空间!还有那个。[[

#2


88  

You can also put the exclamation point inside the brackets:

你亦可在括号内加上感叹号:

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

but you should anchor your pattern to reduce false positives:

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

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

which looks for a match at the beginning or end with a colon before or after it (or both). I recommend using lowercase or mixed case variable names as a habit to reduce the chance of name collisions with shell variables.

它在开始或结束时查找匹配,并在其之前或之后使用冒号(或两者都使用)。我建议使用小写或混合的case变量名作为一个习惯,以减少与shell变量发生名称冲突的机会。

#3


16  

the safest way is to put the ! for the regex negation within the [[ ]] like this:

最安全的方法是把!对于[]内的regex否定,如下:

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

otherwise it might fail on certain systems.

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

#4


6  

Yes you can negate the test as SiegeX has already pointed out.

是的,正如西格克斯已经指出的那样,你可以否定这个测试。

However you shouldn't use regular expressions for this - it can fail if your path contains special characters. Try this instead:

但是,如果您的路径包含特殊字符,则不能使用正则表达式。试试这个:

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

(Source)

(源)

#5


2  

I like to simplify the code without using conditional operators in such cases:

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

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