5

Debian 8 的 find 命令的手册页说:

如果整个表达式不包含除 -prune 或 -print 之外的任何操作,则对整个表达式为真的所有文件执行 -print。

那么为什么这些输出不同:

$ mkdir -p test/foo test/bar && cd test && touch foo/bar bar/foo
$ # Test 1
$ find . -name foo -type d -prune -o -name foo
./foo
./bar/foo
$ # Test 2
$ find . -name foo -type d -prune -o -name foo -print
./bar/foo

所以测试 1:表达式是否包含“除了 -prune 或 -print 之外没有其他操作”?好吧,不包括修剪,是的,这句话是真的,没有任何行动。所以这些结果是预期的,因为选项返回 True./foo之前的表达式-o,所以它被打印出来。

但是测试 2:该表达式是否包含“除了 -prune 或 -print 之外没有其他操作”?好吧,不包括修剪和印刷品,是的,这句话又是真的,没有其他动作。所以我希望得到同样的结果。

但我不明白./foo。为什么?

就好像手册页应该这样写:“如果整个表达式不包含除 -prune 之外的任何操作或 - 打印, -print 对整个表达式为真的所有文件执行。"

4

3 回答 3

3

我将使用更简单的解释,手册页是错误的。它应该说

如果整个表达式不包含除 -prune或 -print之外的任何操作,则对整个表达式为真的所有文件执行 -print。

它还应该包含一个警告-quit,这是一个动作,但它会导致-find立即退出。因此,即使-print为整个表达式添加了隐式,它也不会真正执行。

posix find 手册页包含更清晰的解释,尽管它没有扩展gnu版本那么多的操作。

如果不存在表达式,则应使用 -print 作为表达式。否则,如果给定的表达式不包含任何主要的 -exec、-ok 或 -print,则给定的表达式应有效地替换为:

(给定表达式)-打印

gnu所谓的动作中,posix 只定义-exec-ok-print-prune。它没有任何扩展的动作-delete,-ls等等......所以定义匹配更正的gnu一个只省略-prune

以下是一些使用所有 gnufind操作的示例,可以证明这一点。对于所有考虑以下文件结构

$ tree
.
└── file

-删除

$ find -name file -delete
$

-执行命令;

$ find -name file -exec echo '-exec is an action so an implicit -print is not applied' \;
-exec is an action so an implicit -print is not applied
$

-execdir 命令 {} +

$ find -name file -exec echo 'This should print the filename twice if an implicit -print is applied: ' {} +
This should print the filename twice if an implicit -print is applied:  ./file
$

-fls

$ find -name file -fls file
$

-fprint

$ find -name file -fprint file
$

-ls

$ find -name file -ls
1127767338    0 -rw-rw-r--   1 user   user          0 May  6 07:15 ./file
$

-ok 命令;

$ find -name file -ok echo '-ok is an action so an implicit -print is not applied' \;
< echo ... ./file > ? y
-ok is an action so an implicit -print is not applied
$

-okdir 命令;

$ find -name file -okdir echo '-okdir is an action so an implicit -print is not applied' \;
< echo ... ./file > ? y
-okdir is an action so an implicit -print is not applied
$

-打印

#./file would be printed twice if an implicit `-print was applied`
$ find -name file -print
./file
$

-打印0

#./file would be printed twice if an implicit `-print was applied`
$ find -name file -print0
./file$

-printf

$ find -name file -printf 'Since -printf is an action the implicit -print is not applied\n'
Since -printf is an action the implicit -print is not applied
$

-修剪

$ find -name file -prune
./file
$

-退出

$ find -name file -quit
$ find -D opt -name file -quit
...
Optimized command line:
( -name file [0.1] -a [0.1] -quit [1]  ) -a [0.1] -print [1]
于 2016-05-06T10:22:16.717 回答
2

让我们看看这个命令:

find . -name foo -type d -prune -o -name foo

由于-print是默认操作,因此该操作适用于整个表达式集,即-name foo -type d -prune -o -name foo. 所以它与以下相同:

find . \( -name foo -type d -prune -o -name foo \) -print

现在让我们看看这个命令:

find . -name foo -type d -prune -o -name foo -print

根据 比man find expr1 expr2具有更高的优先级expr1 -o expr2。因此,在上面的命令中,两个表达式与 OR 运算符相结合:

  • -name foo -type d -prune
  • -name foo -print

因此,如果您想同时应用-print两者,请使用括号:

find . \( -name foo -type d -prune -o -name foo \) -print

-prune -o RHS意味着RHS只对那些没有被修剪的项目进行评估。

find我们可以通过运行-D treeor来检查我们是否正确-D opt

find -D opt -O0 . -name foo -type d -prune -o -name foo -print
...
 (  ( -name foo [0.1] -a [0.04] [need type] -type d [0.4]  ) -a [0.04] [call stat] [need type] -prune [1]  ) -o [0.14]  ( -name foo [0.1] -a [0.1] -print [1]  ) 
./bar/foo


find -D opt -O0 . -name foo -type d -prune -o -name foo
 (  (  ( -name foo [0.1] -a [0.04] [need type] -type d [0.4]  ) -a [0.04] [call stat] [need type] -prune [1]  ) -o [1] -name foo [0.1]  ) -a [0.14] -print [1] 
./foo
./bar/foo

正如我们所看到的,从我们find明确(... -prune) -o (... -print)放置的第一个表达式中生成-print。它(...) -a -print来自我们省略的第二个表达式-print

所以我认为“整个表达式”手册页是指部分中描述的表达式部分之一OPERATORS

于 2016-05-05T10:13:00.543 回答
0

检查 GNU Findutils 手册,它说

如果表达式不包含除“-prune”之外的任何操作,则对整个表达式为真的所有文件执行“-print”。

显然,debian 的手册是错误的,因为它只是一个GNU Find。我不知道为什么会这样,因为它对我来说只是一个副本。

于 2019-01-21T06:32:50.213 回答