bash脚本中的正则表达式


12

这是我第一次使用bash脚本,所以我很容易犯一个错误。

基本上,我正在尝试编写一个获取用户组的脚本,如果它们在某个组中,它将相应地进行记录。显然会有更多功能,但是当我什至无法使正则表达式正常工作时,毫无意义!

到目前为止,我有这个:

#!/bin/bash

regex="^([a-zA-Z0-9\-_]+ : [a-zA-Z0-9\-_]+) (usergroup)$"

# example output
groups="username : username usergroup"

echo "$groups" >> /home/jrdn/log

if [[ "$groups" =~ $regex ]]; then
    echo "Match!" >> /home/jrdn/log
else
    echo "No match" >> /home/jrdn/log
fi

我尝试过该正则表达式的每个地方都可以使用。但是在bash脚本中,它只输出$groups,然后输出No match。那么有人可以告诉我这是怎么回事吗?


1
是什么让您认为这有什么问题呢?
manatwork 2013年

1
@jrdnhannah然后尝试缓慢地重新创建目标正则表达式,先进行匹配,^([a-zA-Z0-9\-_]+)然后添加冒号,以此类推...您应该很快发现问题所在。
彼得2013年

2
与bash 4.2.45相同。转义下划线即可解决此问题。奇怪的。@jrdnhannah你能写出来作为答案并接受吗?
terdon

1
由于我只是刚刚注册了Unix SE,因此需要我等待8个小时才能回答自己的问题。不过,如果有人这样做,我们很乐意将其标记为已回答。
2013年

4
@terdon bash可能只是调用libc的regex函数。因此,它取决于libc版本,而不取决于bash版本。看到我的答案...(或者甚至在您使用的排序规则上)
derobert

Answers:


13

来自man 7 regex

方括号表达式是用“ []”括起来的字符列表。…

…要包含文字“-”,请使其成为第一个或最后一个字符…。[A]其他特殊字符,包括'\',在方括号表达式中也失去其特殊意义。

使用egrep尝试regexp会出现错误:

$ echo "username : username usergroup" | egrep "^([a-zA-Z0-9\-_]+ : [a-zA-Z0-9\-_]+) (usergroup)$"
egrep: Invalid range end

这是一个更简单的版本,也会给出错误:

$ echo 'hi' | egrep '[\-_]'
egrep: Invalid range end

由于\不是特殊的,所以这是一个范围,就像是[a-z]那样。您需要将自己-放在最后,例如[_-]或:

echo "username : username usergroup" | egrep "^([a-zA-Z0-9_-]+ : [a-zA-Z0-9_-]+) (usergroup)$"
username : username usergroup

无论您的libc版本是什么(egrep或bash),它都应该起作用。

编辑:这实际上也取决于您的区域设置。手册页确实对此发出警告:

范围是非常依赖整理顺序的,可移植程序应避免依赖它们。

例如:

$ echo '\_' | LC_ALL=en_US.UTF8 egrep '[\-_]'
egrep: Invalid range end
$ echo '\_' | LC_ALL=C egrep '[\-_]'
\_

当然,即使它没有出错,它也没有做您想要的事情:

$ echo '\^_' | LC_ALL=C egrep '^[\-_]+$'
\^_

这是一个范围,这在ASCII,包括\[^,和_


有趣。我egrep没有给出任何错误,只是正确地匹配了它。
manatwork

@manatwork您的排列顺序可能允许的范围内....
derobert

我对整理不是很了解。您的意思是:LC_COLLATE="en_US.UTF-8"
manatwork

@manatwork我已经编辑了问题以举一个例子。请注意,它在您的系统上可能有所不同,因为有时这些排序规则(排序)会发生变化。
derobert

1
@manatwork它的好,我几乎递交一个bug报告之前,我注意到了企图逃跑-...
derobert

4

使用正则表达式的一般规则(以及较大代码段中的所有错误):缩减并逐步重建它,或使用平分式-适用于您的任何方法。

在这种情况下,罪魁祸首是下划线-用反斜杠转义可以使它起作用。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.