为什么带可选括号()?的正则表达式在bash find命令中不生效?
find 命令正则匹配失效问题原因及解决方法
核心原因
问题来源于find命令默认正则语法和Python re模块的规则不兼容,外加正则逻辑存在细节错误:
- GNU
find默认使用Emacs 风格正则表达式,该语法下(、)、?这类特殊字符需要加反斜杠转义才会生效,未转义时会被识别为普通字面量字符,自然无法匹配到目标文件名。 - 原正则逻辑存在疏漏:写法
_[0-9]+_([a-zA-Z]+)?\.sql把下划线放在可选分组外,就算正则语法生效,也只能匹配scheme_12_.sql、scheme_23_analytics.sql这类文件名,无法匹配scheme_12.sql(数字后会多出来一个无匹配内容的下划线)。 - 额外冗余操作:
ls | find的写法完全多余,find本身就会遍历当前目录文件,管道接ls没有任何作用,还可能引入不可预期的问题。
解决方法
方法1:适配find默认的Emacs正则语法
调整正则的转义规则和逻辑结构,命令如下:
find . -type f -regex "\./scheme_[0-9]+\(_[a-zA-Z]+\)?\.sql"
方法2:指定使用扩展正则语法
给find添加-regextype posix-extended参数,即可使用和Python re一致的正则语法,无需额外转义特殊符号:
find . -type f -regextype posix-extended -regex "\./scheme_[0-9]+(_[a-zA-Z]+)?\.sql"
补充说明
你去掉可选部分的命令可以正常运行,是因为该命令没有用到()、?这类需要转义的特殊字符,且未转义的.sql中的.刚好匹配到了文件名末尾的.,属于巧合性生效,实际写法不规范。
内容的提问来源于stack exchange,提问作者user10465614
相关产品推荐
相关产品推荐

