我有以下文件夹结构:
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