如何发现“修剪”行为?

时间:2019-10-24 13:27:31

标签: bash find

根据GNU find的联机帮助页,默认情况下使用-print操作,并且

  

禁止默认的-print的动作是-delete-exec-execdir-ok-okdir-fls-fprint-fprintf-ls-print-printf

因此,-prune动作仍应暗示-print动作。

实际上是。

$ tree .
.
├── dir/
│   └── file2
└── file1

$ find . -name dir #0
./dir

$ find . -name dir -prune #1
./dir #printed as expected

$ find . -name dir -prune -or -name file1 #2
./file1
./dir #printed as expected

但是,有时-prune禁止使用默认的-print

$ find . -name dir -prune -or -name file1 -print #3 #last -print is only added to the above example
./file1

$ find . -name dir -prune -or -print #4
.
./file1

我如何理解这个矛盾?


我的理解

#1

  1. file1不能满足-name dir的要求,因此被跳过。

  2. dir满足-name dir的要求,因此将其修剪并将dir添加到TODO列表中。

  3. -print还将应用于TODO列表中的dir

#2

  1. file1满足-name file1的要求,因此已添加到TODO列表中。

  2. #1-2

  3. -print还将应用于TODO列表中的dirfile1

#3

  1. #2-1

  2. #2-2

  3. -print应用于TODO列表中的file1

  4. -print 应该另外应用于dir,因为-prune不会禁止-print。 (但这是不正确的。为什么?)

#4

  1. file1已添加到TODO列表。

  2. #3-2

  3. #3-3

  4. #3-4

(实际上,{{1}中没有TODO列表。请参见this commentthe standard。)


补充

正如oguz ismail's answer(现已删除)中指出的那样,我的问题与find无关。但是,问题尚未解决。

让我们考虑一下-prune。这分为两个表达式:-name A -o -name B -print-name A

我的理解:第一个表达式-name B -print没有动作。因此,应暗示-name A。换句话说,-print应该解释为-name A -o -name B -print

实际行为:-name A -print -o -name B -print是一种复合表达式。此复合表达式中有-name A -o -name B -print。因此,不应暗示其他-print

存在歧义,但我相信我的解释会更自然,因为在这种情况下,每个文件仅满足-print-name A(两个表达式从不同时满足)

1 个答案:

答案 0 :(得分:2)

正如this commentthis comment所写,我的问题(在OP的补充部分中进行了总结)来自于GNU {{1 }}和POSIX有更好的解释。我发现这是真的。

POSIX

  

(如果不存在表达式,则将find用作表达式。否则,)如果给定表达式不包含任何主变量-print-exec或{ {1}},给定的表达式应有效地替换为:

     

-ok

并且很自然地解释-print是由一个或多个子表达式组成的复合表达式,因为它在括号中是封闭的。 (如果此( given_expression ) -print引用单个子表达式,则括号肯定是多余的。)