GNU find:默认操作何时适用?

时间:2016-05-05 09:43:42

标签: linux find gnu-findutils

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之外的其他动作?”好吧,除了修剪,是的,这句话是真的,没有行动。所以这些结果是预期的,因为对于./foo -o选项之前的表达式返回True,所以它被打印出来。

但测试2:表达式是否包含“除-prune或-print之外的其他动作?”好吧,不包括修剪和印刷品,是的,该陈述再次成立,没有其他行动。所以我希望得到相同的结果。

但我没有得到./foo。为什么?

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

3 个答案:

答案 0 :(得分:3)

我采用更简单的解释,手册页错误。应该说

  

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

它也可能包含-quit的警告,这是一个动作,但它会导致-find立即退出。因此,即使为整个表达式添加了隐式-print,它也永远不会被实际执行。

posix find man page包含更清晰的解释,但它的动作与扩展的gnu版本相同。

  

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

     

(given_expression)-print

gnu调用操作中,posix仅定义-exec-ok-print-prune。它没有任何展开的操作-delete-ls等...因此,只有省略gnu,定义才会与更正的-prune匹配。

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

$ tree
.
└── file

<强> -delete

$ find -name file -delete
$

-exec command;

$ 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 command {} +

$ 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
$

-print

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

<强> -print0

#./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
$

<强> -prune

$ find -name file -prune
./file
$

<强> -QUIT

$ 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]

答案 1 :(得分:2)

让我们看一下这个命令:

-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,优先级高于-name foo -type d -prune。因此,在上面的命令中,两个表达式与OR运算符组合在一起:

  • -name foo -print
  • -print

因此,如果您要将find . \( -name foo -type d -prune -o -name foo \) -print 应用于两者,请使用括号:

-prune -o RHS

但是RHS意味着find仅针对那些未被修剪的项目进行评估。

我们可以通过-D tree-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

所以我认为通过“整个表达式”,手册页意味着for(i = 0;i<hour;i++){ if(volt[i] > f || volt[i] <af){ printf("there was an error at hour: %d with the voltage: %.1f\n",i+1, volt[i]); } } 部分中描述的表达部分之一。

答案 2 :(得分:0)

Check the GNU Findutils manual,它说

  

如果表达式中除“ -prune”外没有其他动作,则“ -print”为   在整个表达式为真的所有文件上执行。

显然,debian's manual是错误的,因为它只是一个 GNU 查找。而且我不知道为什么会这样,因为这只是我的副本。