find
(对于-name
/ -path
标准谓词)与通配符一样使用通配符模式(请注意,{a,b}
它不是通配符运算符;展开后,将得到两个通配符)。主要区别在于对斜杠(以及未在中特别处理的点文件和目录find
)的处理。*
在全球范围内不会跨越几个目录。*/*/*
将导致最多列出2级目录。添加a -path './*/*/*'
将匹配至少3层深度的任何文件,并且不会停止find
列出任何深度的任何目录的内容。
对于那个特殊的
./foo*bar/quux[A-Z]{.bak,}/pic[0-9][0-9][0-9][0-9]?.jpg
几个问题,翻译起来很容易,您想要目录3的深度,因此可以使用:
find . -mindepth 3 -maxdepth 3 \
\( -path './foo*bar/quux[A-Z].bak/pic[0-9][0-9][0-9][0-9]?.jpg' -o \
-path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg' \) \
-exec cmd {} +
(或-depth 3
带有某些find
实现)。或POSIXly:
find . -path './*/*/*' -prune \
\( -path './foo*bar/quux[A-Z].bak/pic[0-9][0-9][0-9][0-9]?.jpg' -o \
-path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg' \) \
-exec cmd {} +
这将保证那些*
和字符?
不能匹配/
。
(find
,与glob相反,它将读取foo*bar
当前目录¹中目录以外的目录的内容,而不对文件列表进行排序。但是,如果撇开/ ,无效字符[A-Z]
的行为或*
/ 的问题?
是未指定,您将获得相同的文件列表)。
但是无论如何,正如@muru所示,find
如果只是将文件列表分成多个运行以解决execve()
系统调用的限制,则无需求助。某些外壳(如zsh
(带有zargs
)或ksh93
(带有command -x
))甚至对此具有内置支持。
用zsh
(其glob也具有-type f
和find
谓词等价的谓词),例如:
autoload zargs # if not already in ~/.zshrc
zargs ./foo*bar/quux[A-Z](|.bak)/pic[0-9][0-9][0-9][0-9]?.jpg(.) -- cmd
((|.bak)
与glob运算符相反{,.bak}
,(.)
glob限定符与find
s 等效-type f
,oN
在其中添加以跳过与的排序find
,D
包括点文件(不适用于此glob))
¹要find
像globs一样爬网目录树,您需要类似以下内容:
find . ! -name . \( \
\( -path './*/*' -o -name 'foo*bar' -o -prune \) \
-path './*/*/*' -prune -name 'pic[0-9][0-9][0-9][0-9]?.jpg' -exec cmd {} + -o \
\( ! -path './*/*' -o -name 'quux[A-Z]' -o -name 'quux[A-Z].bak' -o -prune \) \)
也就是说,修剪所有级别为1的目录(除去目录)foo*bar
,以及所有级别2的除quux[A-Z]
或quux[A-Z].bak
,然后选择pic...
级别3的目录(并修剪该级别的所有目录)。
-path
或一起使用-ipath
。find . -path './foo*bar/quux[A-Z]/pic[0-9][0-9][0-9][0-9]?.jpg'
应该工作-除了匹配/fooz/blah/bar/quuxA/pic1234d.jpg
。那会是个问题吗?