Linux技巧:find 命令简单入门介绍和问题点解析( 四 )


使用 -and 操作符组合的表达式要求两个表达式都是 true,该组合表达式才是 true 。
左边的 expr1 表达式为 false 时,不再评估右边的 expr2 表达式,该组合表达式会返回 false 。
上面例子的 find . -path tests 命令什么都没有打印,就跟 -and 操作符的特性有关 。
由于该命令没有提供 action 类型表达式,默认会加上 -print 表达式,也就是 find . -path tests -print 。
由于在 -path tests 和 -print 之间没有提供操作符,默认会加上 -and 操作符,也就是 find . -path tests -and -print 。
而 find . 命令搜索到的所有文件名都不匹配 -path tests 模式,都返回 false,基于 -and 操作符的特性,不往下执行 -print 表达式,也就不会打印任何文件名 。
-prune这是一个 action 类型表达式,GNU find 在线帮助手册对该表达式的说明如下:

Action: -prune
If the file is a directory, do not descend into it. The result is true.
For example, to skip the directory src/emacs and all files and directories under it, and print the names of the other files found:
find . -wholename './src/emacs' -prune -o -print
The above command will not print ./src/emacs among its list of results. This however is not due to the effect of the ‘-prune’ action (which only prevents further descent, it doesn’t make sure we ignore that item).
Instead, this effect is due to the use of ‘-o’. Since the left hand side of the “or” condition has succeeded for ./src/emacs, it is not necessary to evaluate the right-hand-side (‘-print’) at all for this particular file.
这里举的例子就类似于我们现在讨论的例子,里面也解释了查找时能够忽略目录的原因,可供参考 。
前面提到,find 命令会把搜索到的每一个文件名都依次作为参数传递给后面的表达式进行评估 。
如果传递到 -prune 表达式的文件名是一个目录,那么不会进入该目录进行查找 。
这个表达式的返回值总是 true 。
具体举例说明如下:
$ find . -path *test* -prune./tests$ find . -path *test* -o -prune.前面例子提到,find . -path *test* 会匹配到 ./tests 目录和该目录下的 ./tests/bre.tests 文件 。
而这里的 find . -path *test* -prune 只匹配到 ./tests 目录,没有进入该目录下查找文件,就是受到了 -prune 表达式的影响 。
基于前面的说明,find . -path *test* -prune 相当于 find . -path *test* -and -prune -and print 。
对于不匹配 *test* 模式的文件名,-path *test* 表达式返回 false,不往下处理,不打印不匹配的文件名 。
对于匹配 *test* 模式的文件名,-path *test* 表达式返回 true,会往下处理,遇到 -prune 表达式 。该表达式总是返回 true,继续往下处理 -print 表达式,打印出该目录名 。
由于 -prune 表达式指定不进入对应的目录,所以没有查找该目录下的文件,没有查找到 ./tests/bre.tests 文件 。
-o这是一个 operator 操作符,GNU find 在线帮助手册对该操作符的说明如下:
expr1 -o expr2
expr1 -or expr2
Or; expr2 is not evaluated if expr1 is true.
使用 -o 操作符组合的表达式要求两个表达式都是 false,该组合表达式才是 false 。
左边的 expr1 表达式为 true 时,不再评估右边的 expr2 表达式,该组合表达式会返回 true 。
前面提到, find . -path tests 命令什么都没有打印,跟使用了 -and 操作符有关,如果改成 -o 操作符,结果就会不一样 。
具体举例如下:
$ find . -path tests -o -print../src./src/main.c./tests./tests/bre.tests./Makefile.am$ find . -path ./tests -o -print../src./src/main.c./tests/bre.tests./Makefile.am可以看到,find . -path tests -o -print 命令打印了当前目录下的所有文件名 。
由于 -path tests 什么都匹配不到,都返回 false,基于 -o 操作符的特性,全都执行后面的 -print 表达式,打印所有文件名 。
这个结果跟 find . -path tests 命令完全相反 。
类似的,find . -path ./tests -o -print 命令的打印结果跟 find . -path ./tests 命令也相反 。
前者的打印结果不包含 ./tests 目录名,后者的打印结果只包含 ./tests 目录名 。
对于匹配 -path ./tests 模式的目录名,该表达式返回 true,基于 -o 操作符的特性,不往下执行 -print 表达式,所以不打印该目录名 。
-print这是一个 action 类型表达式,GNU find 在线帮助手册对该表达式的说明如下:
Action: -print
True; print the entire file name on the standard output, followed by a newline.
前面例子已经说明过 -print 表达式的作用,它会打印传递下来的完整文件路径名,会自动添加换行符 。


推荐阅读