使用文件夹排除来加速查找命令结果

使用文件夹排除来加速查找命令结果

我有以下文件夹结构:

Approvals_Share
    1 CUST APPROVAL
    2 LICENSE APPROVAL
    CANADA INSCRIBE
    z-remove

每个文件夹内有多个子文件夹和插画文件“.ai”

如果我对每个文件夹单独执行操作,find我会在下面方括号内指定的时间内得到结果:

1 CUST APPROVAL: [14m 19s]
2 LICENSE APPROVAL: [10m 17s]
CANADA INSCRIBE: [13s]
z-remove: [2s]

z-remove下面是我用来列出文件夹的示例 shell 命令

cd '/Volumes/Box/Approvals_Share/z-remove/'
find .  -name '*.ai' -not -name '.*' > output.txt

此任务仅需 2 秒即可完成,但如果我在父文件夹上运行相同的命令Approvals_Share(排除所有文件夹),则z-remove该任务需要 3 分 27 秒。我原本预计需要 2 秒或更短。这是我使用的 shell 命令:

cd '/Volumes/Box/Approvals_Share/'
find .  -name '*.ai' -not -name '.*' -not -path './2 LICENSE APPROVAL/*' -not -path './1 CUST APPROVAL/*' -not -path './CANADA INSCRIBE/*' > output.txt

有没有什么办法可以加快结果呢?

答案1

使用not -path需要遍历所有排除的目录并忽略输出,这是花费更多时间的原因。

这里的解决方案是使用-prune,它禁止find访问-path选项中每个模式的子项:

cd /Volumes/Box/Approvals_Share/
find . -path './2 LICENSE APPROVAL' -prune -o -path './1 CUST APPROVAL' -prune -o -path './CANADA INSCRIBE' -prune -o -name '*.ai' -not -name '.*' -print

另一种方法是对排除的目录进行分组:

find . -type d \( -path './2 LICENSE APPROVAL' -o -path './1 CUST APPROVAL' -o -path './CANADA INSCRIBE' \) -prune -o -name '*.ai' -not -name '.*' -print

答案2

其他答案是正确的,但它要求您明确指定要排除的所有目录。该解决方案扩展性不佳。如果 中有数百个目录怎么办.

您的要求是排除除 和 之外的所有目录z-remove.首先隐式地排除,否则就没有意义了)。更具可扩展性的解决方案应该仅指定z-remove(和.),因为此信息足以排除其余目录。

如果您知道 中没有直接匹配的文件,.那么所有文件(如果有的话)都将位于 中z-remove。在这种情况下,请使用这种直接的方法:

find z-remove -name '*.ai' ! -name '.*'

(注意:我使用它是!因为它是 POSIX,而-not不是。)

如果在 中直接有匹配的文件,.那么您需要从 开始.(显然)并修剪不在../z-remove或 内的每个目录./z-remove。像这样:

find . -type d ! -path . ! -path ./z-remove ! -path './z-remove/*' -prune \
       -o -name '*.ai' ! -name '.*' -print

请注意,您的原始代码不使用-type f,因此目录./z-remove/foo.ai将通过所有测试。您谈论的是 Unix 中的文件和目录也是一个文件。但是您说的是“illustrator 文件”,所以也许您指的是常规文件,而-type f这正是您想要的。如果是这样,我的解决方案是:

find . -type d ! -path . ! -path ./z-remove ! -path './z-remove/*' -prune \
       -o -type f -name '*.ai' ! -name '.*' -print

相关内容