Bash中find命令正则匹配非单词字符等内容失效问题求助
问题:Bash脚本匹配含特殊字符/德语变音符号的文件/文件夹
我正在写Bash脚本,需要匹配当前目录下包含非单词字符、大写字符或德语变音符号的所有文件和文件夹。在测试目录里试了好几种正则组合,要么全匹配要么完全不匹配,搞不清是字符类用错了还是Bash本身的特性导致的。
测试环境与命令
当前目录下的文件/文件夹:
$ ls kukukae.txt KuKuKä.txt 'Replüce-?!% Test.txt.bak' repluece_test.txt.bak 'Sä=?)(&%$§"!°^`´+*~#' somo_oemo.gif 'Somo Ömo.gif' super_ 'why?that' # 部分示例文件和一个文件夹
尝试的find命令及结果:
- 无匹配结果
$ find . -maxdepth 1 -regex '[^\w\.\/]'
- 错误匹配了不含目标字符的文件(比如
super_、kukukae.txt)
$ find . -maxdepth 1 -regex '.*[^\w\.\/].*' ./super_ ./kukukae.txt ./Sä=?)(&%$§!°^`´+*~# ./somo_oemo.gif ./repluece_test.txt.bak ./why?that ./KuKuKä.txt ./Replüce-?!% Test.txt.bak ./Somo Ömo.gif
- 再次无匹配
$ find . -maxdepth 1 -regex '[[:upper:]]|[[:space:]]|[\?\&\ä\ü\ö\!\\"\§\$\\(\)\[\]\}\{\=\`\´\+\*\~\#\:\;\,\^\°\<\>\|]'
- 仍然无匹配
$ find . -maxdepth 1 -regex '.*[[:upper:]]|[[:space:]]|[\?\&\ä\ü\ö\!\\"\§\$\\(\)\[\]\}\{\=\`\´\+\*\~\#\:\;\,\^\°\<\>\|].*'
期望匹配结果
只筛选出包含非单词字符、大写字符或德语变音符号的文件/文件夹:
$ find [可用命令] ./Sä=?)(&%$§!°^`´+*~# ./why?that ./KuKuKä.txt ./Replüce-?!% Test.txt.bak ./Somo Ömo.gif
注:我不想匹配/或.(用[^\w\.\/]的原因),因为这会包含路径分隔符和文件扩展名的点。
解决方案
问题核心是find默认使用Emacs正则表达式,和常用的PCRE语法差异较大,且字符类的处理逻辑不同。以下两种方法可以解决:
方法1:使用扩展正则表达式(ERE)
通过-regextype posix-extended指定正则类型,编写符合ERE的匹配规则:
find . -maxdepth 1 -regextype posix-extended -regex '.*/([A-ZÄÖÜ]|[^a-z0-9_.\/])+'
.*/:匹配路径前缀(如./)([A-ZÄÖÜ]|[^a-z0-9_.\/])+:匹配至少一个大写字母(含德语变音ÄÖÜ),或非小写字母、数字、下划线、点、斜杠的字符
方法2:用通配符组合(更简洁)
如果不需要复杂正则,直接用find的通配符匹配更直观:
find . -maxdepth 1 \( -name '*[A-ZÄÖÜ]*' -o -name '*[^a-z0-9_.]*' \) ! -name '.'
-name '*[A-ZÄÖÜ]*':匹配含大写字母(含德语变音)的文件-o:逻辑或-name '*[^a-z0-9_.]*':匹配含非小写字母、数字、下划线、点的文件! -name '.':排除当前目录本身
这两种方法都能得到你想要的匹配结果。
内容的提问来源于stack exchange,提问作者lukeflo
相关产品推荐
相关产品推荐

