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

Dav*_*ers 153 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
Run Code Online (Sandbox Code Playgroud)

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

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
Run Code Online (Sandbox Code Playgroud)

Sie*_*geX 170

你说得对,只是把之间的空间![[类似if ! [[

  • Oye vey!就在我安全地回避perl的星际特殊性格疯狂时,我发现自己迷失在bash空间(放置)!(我觉得害怕像蟒蛇一样挤压我的肠道.)谢谢! (13认同)
  • 你确定它总是在 `[[` 之前而不是在里面,就像 `if [[ ! "$value" =~ $regex ]];`? 例如,Sublime Text 在外部会奇​​怪地突出显示它:https://i.imgur.com/AQWuFtf.png (4认同)

Pau*_*ce. 110

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

if [[ ! $PATH =~ $temp ]]
Run Code Online (Sandbox Code Playgroud)

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

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

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

  • @anyoneis信任我们.应避免使用用户定义的大写变量.bash中的所有变量都使用`$`进行扩展,因此没有理由将它们大写以使它们脱颖而出. (4认同)

小智 17

最安全的方法是把!对于这样的正则表达式否定[[ ]]:

if [[ ! ${STR} =~ YOUR_REGEX ]]; then
Run Code Online (Sandbox Code Playgroud)

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


Mar*_*ers 7

是的,你可以否定测试,因为SiegeX已经指出.

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

[[ ":$PATH:" != *":$1:"* ]]
Run Code Online (Sandbox Code Playgroud)

(资源)

  • 使用这种形式的另一个原因是它不会意外匹配子字符串(例如,无法将“/bin”添加到路径中,因为“/usr/bin”已经存在)。 (2认同)

dim*_*mir 6

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

TEMP=/mnt/silo/bin
[[ ${PATH} =~ ${TEMP} ]] || PATH=$PATH:$TEMP
Run Code Online (Sandbox Code Playgroud)