我需要在一个相当大的目录层次结构中搜索名称与特定文件名通配模式匹配的常规文件。层次结构是如此之大(非常深并且有一些巨大的目录),以至于采取幼稚的方法需要很长时间:
find /top/dir -type f -name 'pattern'
pattern
(像 . 的一些模式在哪里*proj*.tgz
。)
由于目录结构的性质,我知道如果find
在目录中找到文件,我可以引入优化来修剪搜索树。例如,在特定目录中找到一个或多个文件意味着我不需要检查该特定目录的任何子目录以查找其他匹配项。
由于应用-prune
到常规文件没有做正确的事情,我不能只是做
find /top/dir -type f -name 'pattern' -prune
问题:如何避免搜索包含与模式匹配的文件的目录的子目录?
可以为每个目录调用一个内联脚本。该脚本将检查该模式是否与目录中的任何常规文件匹配。如果模式匹配,它会输出(在一般情况下,处理而不只是打印)匹配的路径名并从搜索树中修剪父目录:
我正在
zsh
为内联脚本使用 shell 来访问该 shell 的通配符。此处使用的限定符(.N)
, 确保只有常规文件与模式匹配,如果没有匹配的文件则删除模式。用于
bash
内联脚本:也就是说,让内联脚本循环遍历特定目录中与模式匹配的名称,如果有任何名称对应于常规文件,则对其进行处理并设置一个“标志”。如果最后设置了标志,则修剪父目录。
遍历目录的层次结构,如果找到标志文件 ( ),则在每个目录中修剪树
pattern
,否则搜索想要的文件 (*proj*.tgz
)我最终写了一个更复杂的版本,让我看到发生了什么。显然,我必须更改与本地相关的项目
/top/dir
,pattern
和*proj*.tgz
。)我将把它包括在这里以供后代使用真正的解决方案需要非 POSIX
find -maxdepth
。调试版本也需要非 POSIXfind -printf
。有一种替代方法可以满足-maxdepth
POSIX,但我没有在这里使用它;代码本身就足够不透明。