我也很困惑为什么find命令也会打印修剪后的目录,以及其他一些如何-prune工作的复杂细节,但是我能够通过一些示例来弄清楚。
要运行以下示例,请创建以下目录和文件。
mkdir aa
mkdir bb
touch file1
touch aa/file1
touch bb/file3
要创建此结构:
$ tree
.
├── aa
│ └── file1
├── bb
│ └── file3
└── file1
现在使用find查找名为的目录aa。没问题
$ find . -type d -name aa
./aa
查找除aa以外的所有目录,我们得到当前目录.和./bb,这也很有意义。
$ find . -type d ! -name aa
.
./bb
到目前为止,一切都很好,但是当使用时-prune,find返回正在修剪的目录,这最初使我感到困惑,因为我期望它返回所有其他目录,而不是正在修剪的目录。
$ find . -type d -name aa -prune
./aa
解释了它返回被修剪目录的原因,而不是-prune在Timo的答案所示的手册页部分中说明,而是在该EXPRESSIONS部分中说明:
如果表达式包含比其他任何动作-prune,
-print是在该表达式为true的所有文件执行。
这意味着,由于表达式与aa目录名匹配,因此表达式将求值为true并被打印,因为find -print在整个命令的末尾隐式添加了a 。-print但是,如果您有意-o -print自己将操作添加到结尾,则不会添加:
find . -type d -name aa -prune -o -print
.
./file1
./bb
./bb/file3
在这里,find命令-print不再添加隐式命令,因此aa将不会打印正在修剪的目录()。
所以最后,如果我们增加一个条款,对于具有的文件名模式的文件搜索file*后-o,那么你必须把-print在像这样的第二句话结束:
find . \( -type d -name aa -prune \) -o \( -type f -name 'file*' -print \)
./file1
./bb/file3
起作用的原因是相同的:如果您未-print在第二个子句中放置a ,则由于除了该-prune动作外没有其他动作,find将-print在命令的THE END处自动添加一个,导致该-prune子句打印修剪目录:
find . \( \( -type d -name aa -prune \) -o \( -type f -name 'file*' \) \) -print
./aa
./file1
./bb/file3
通常,您需要将-print命令放在第二个子句中。如果像原始海报一样将其放置在中间,它将无法正常工作,因为被修剪的文件将立即打印出来,第二子句将没有机会选择想要的文件:
find . \( -type d -name aa -prune -o -print \) -o \( -type f -name 'file*' \)
.
./file1
./bb
./bb/file3
因此,很不幸,原始海报将放置-print在错误的位置,从而使上面的命令错误。它可能适用于他的特定情况,但在一般情况下不起作用。
成千上万的人难以理解其-prune工作原理。该find手册页应以防止此命令的无止境的全球混乱更新。
-print,否则隐含-print适用于整个状态