我无法弄清楚我的正则表达式出了什么问题,它似乎可以与 一起使用,grep
但现在可以与find
.我试图找到遵循电视节目中常见表达的所有文件,例如S02E21。
find -E . -name '.*[sS]{1}[0-9]{1,2}[\.]?[eE]{1}[0-9]{1,2}.*\.mkv'
我没有得到任何结果find
,但是如果我将相同的正则表达式与 结合使用ls|grep -E '....'
,则会按预期找到文件。
答案1
-name
需要通配符模式,不是正则表达式,并且匹配文件名,而不是其完整路径。使用-regex
(或-iregex
) 进行正则表达式匹配,但要注意它与完整路径匹配。在这里,你可以这样做:
LC_ALL=C find -E . -iregex '.*s[0-9]{1,2}\.?e[0-9]{1,2}[^/]*\.mkv'
在这里,我们将第二个替换.*
为[^/]*
,这是一系列非 / 字符,以确保它之前的模式与文件名匹配,而不是与任何目录组件匹配。
通过将语言环境固定为 CLC_ALL=C
,我们确保.
匹配任何字节和[^/]
除 for 之外的任何字节,/
否则您可能会遇到以与您的语言环境不同的字符集编码的文件或目录名的问题。将语言环境固定为 C 还可以保证e
仅与e
和E
(以及s
和s
)S
与匹配-iregex
。
请注意,[\.]
匹配反斜杠或点。要匹配点,可以是\.
或[.]
。 Alsox{1}
与 相同,因此为了简化x
我删除了它们。{1}
查看你的手册页了解详情。请注意-E
,-regex
或都不-iregex
是标准。
可以简化为
LC_ALL=C find -E . -iregex '.*s[0-9]{1,2}\.?e[0-9][^/]*\.mkv'
作为第二个数字,如果有的话,无论如何也会匹配[^/]
。
使用通配符模式的标准等效项如下所示:
LC_ALL=C find . -name '*[sS][0-9][0-9].[eE][0-9]*.mkv' \
-o -name '*[sS][0-9].[eE][0-9]*.mkv' \
-o -name '*[sS][0-9][0-9][eE][0-9]*.mkv' \
-o -name '*[sS][0-9][eE][0-9]*.mkv'
与扩展正则表达式相反,通配符模式没有交替运算符,也没有等效的?
or {n,p}
,因此我们需要 4 种模式来涵盖所有可能性。
您还可以使用具有递归通配符和高级通配符模式的 shell,例如zsh
:
setopt extendedglob
ls -lrtd -- **/(#i)*s<->e<->*.mkv
**/
递归搜索(#i)
不区分大小写的匹配<->
任何小数
传递到ls -lrtd
此处打印包含详细信息的列表,按上次修改时间排序,当然您可以使用任何命令。
答案2
find dir -name
仅支持 shell 文件名 glob 字符,如 man fnmatch
.
一些查找实现支持正则表达式的非标准扩展。检查你的find
手册页。