为何find命令的正则表达式需转义?附实例验证
find命令-regex参数的正则表达式语法问题
假设我有3个文件,路径如下:
/tmp/test/c /tmp/test/a /tmp/test/b
想要用find命令排除其中的a和b两个文件,以下命令可以正常运行:
# 正常运行 find /tmp/test -type f -not -regex "/tmp/test/\(a\|b\)"
但下面这个命令却无法生效:
# 无法运行 find /tmp/test -type f -not -regex "/tmp/test/(a|b)"
单引号或双引号对结果没有影响,这是为什么?我原本以为正则表达式被引号包裹后,Shell不会处理它,所以不需要转义。
原因解析
问题出在find命令默认使用的正则表达式语法上:
- find默认采用的是基本正则表达式(BRE),在BRE语法里,括号
()和竖线|属于普通字符,要让它们发挥分组和分支匹配的作用,必须加上反斜杠转义,也就是写成\( \)和\|,这就是第一个命令能正常工作的原因。 - 第二个命令里用的
(a|b)是**扩展正则表达式(ERE)**的语法,find默认不识别这种写法,所以无法匹配到目标文件,自然也就达不到排除的效果。
如果想用ERE语法而不转义,也可以给find加上-regextype参数指定使用扩展正则表达式,比如:
find /tmp/test -type f -not -regextype posix-extended -regex "/tmp/test/(a|b)"
内容的提问来源于stack exchange,提问作者bill
相关产品推荐
相关产品推荐

