Linux find命令的几个备忘

Linux find命令的几个备忘

下面的内容只是我在使用Linux的find命令时候遇到的几个小问题,在这里做一个记录,更详细的find命令的使用参考man手册。

1. -name | -path中的pattern是精准匹配

首先我们看一下-name的几个示例:

liuxingen@V6-Dev ~/station/test $ ls
test.py test.pyc
liuxingen@V6-Dev ~/station/test $ find ./ -name “*.py”
./test.py

我说的精准匹配就是说find根据pattern去做匹配的时候除了”正则表达式”、”通配符”会做扩展以外,其它部分都是要100%匹配才行。上面示例我们指定的pattern为”*.py“那么匹配查找的时候那么文件名就必须要以py结尾,我们看到目录下面test.pyc文件没有匹配成功,虽然文件名能够匹配.py,但是后面还有一个c

liuxingen@V6-Dev ~/station/test $ ls
plugins test.py test.pyc
liuxingen@V6-Dev ~/station/test $ find ./ -path “plugins”
liuxingen@V6-Dev ~/station/test $ find ./ -path “./plugins”
./plugins
liuxingen@V6-Dev ~/station/test $ find ./ -path “./plugins/”
liuxingen@V6-Dev ~/station/test $ find ./ -path “./plugins/*”
./plugins/www
./plugins/www/httplib.py

上面-path的示例中需要注意的一点就是find ./ -path “./plugins”这条命令,必须要要以./开头,因为我们是在当前目录./查找,那么这样查找出来的文件都是以./前缀开头的,而pattern我们已经说过是精准匹配的,所以必须要以“./plugins”来进行查找。

2. -maxdepth组合性能问题

liuxingen@V6-Dev ~/station/test $ find ./ -type f -maxdepth 1
find: warning: you have specified the -maxdepth option after a non-option argument -type, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.

./test.py
./test.pyc

上面的一条find语句报出来了一个warning,大意就是如果把maxdepth放在type之后会影响性能,最好是把maxdepth放到type之前。
为什么会有性能问题呢?按照find的执行逻辑会先找出类型为普通文件的文件(-type f),然后再判断这个文件是否超过了最大的目录深度1(-maxdepth 1),这样其实会把所有的普通文件遍历一遍,即使这些文件的目录深度超过了1。这样查找肯定会很慢了,如果把-maxdepth放在-type前面的话那么就最多只会查找当前目录下面的所有文件,这样会快很多了。

3. -prune选项

-prune就像一个判断语句,当发现-prune前面的表达式匹配,那么执行到-prune的时候就会输出True,如果没有匹配那么就输出一个False。如果我们-prune后面跟着的是-o -print,那么就相当于True || -print、False || -print。也就是说-prune前面的表达式成立的话,就不会执行-o后面的-print,如果表达式不成立,那么就会执行-o后面的-print。
下面的示例是查找除www目录以外的py文件:

liuxingen@V6-Dev ~/station/test $ tree
.
├── plugins
│     └── www
│             └── httplib.py
├── test.py
├── test.pyc
└── www
        └── test_www.py

3 directories, 4 files

liuxingen@V6-Dev ~/station/test $ find ./ -path “./www” -prune -o -name “*.py” -print
./test.py
./plugins/www/httplib.py

liuxingen@V6-Dev ~/station/test $ find ./ ! -path “./www*” -name “*.py”
./test.py
./plugins/www/httplib.py

从上面示例来看我们可以用取非运算符来达到同样的效果。
很多时候我们在查找源码文件的时候需要排除.svn目录,那么我们可以用如下的命令:

find ./ -path “./.svn” -prune -o -name “*.py” -print

4. -exec选项

-exec后面可以有两种方式:

liuxingen@V6-Dev ~/station/test $ find ./ -name “*.py” -exec ls {} \;
./test.py
./plugins/www/httplib.py
./www/test_www.py
liuxingen@V6-Dev ~/station/test $ find ./ -name “*.py” -exec ls {} +
./plugins/www/httplib.py ./test.py ./www/test_www.py

+的方式跟相比有一定的优势,因为+只会对查找出来的文件统一执行一次exec后面的命令,而会对查找出来的文件分别执行exec后面的命令。
还有前面需要加入转移符\,因为这种方式下find需要把作为输入参数的结束标志,如果不转义那么就会被shell自身解释(要知道shell中把作为命令分隔符)。

你可能感兴趣的:(linux,shell,find,exec,prune)