find命令可以找出符合要求的所有文件并执行额外的命令。find会遍历文件系统,将找到的文件名交给谓词测试。如果谓词返回真,就通过。如果谓词返回假,则不再继续往下进行,会接着处理下一个文件名。
谓词:find命令的选项看起来像是简短的单词,事实上它们是find命令的表达式选项、测试条件或操作。这些单词依照逻辑顺序出现,并描述要查找哪些文件以及如何处理查找到的文件。这种像单词一样的选项通常被称为谓词。
如:
find . -name '*.mp3' -print -exec mv '{}' ~/songs \;
find命令的第一个参数待搜索的目录。典型用法是用点号(.)代表当前目录,也可以根据需要提供其他目录。
示例中的第一个选项(谓词-name)指定了要搜索的文件模式。匹配该模式的文件被认为返回的是真(true),接着将其交给下一个下一个谓词进行处理。
谓词-print很简单,它总是返回真,同时会将文件名打印到标准输出。因此能在谓词测试中通过测试而达到这一步的文件都会输出其名称。
-exec:达到这一步的文件名会变成接下来要执行的命令的一部分。剩下的一直到\;的这部分就是命令。其中的{}会被替换成已经查找到的文件名。
-delete:删除查找到的文件
-print0:可以与xargs -0 选项合用处理文件名中的怪异字符。-print0告诉find不要用空白字符,而是改用空字符(null character)(\0)作为输出的文件名之间的分隔符。xargs的-0选项告诉xargs输入分隔符是空字符。
xargs从标准输入中接收以空白字符分割(指定-0时除外)的文件名,然后对尽可能多的文件(略少于系统ARG_MAX值)执行指定命令。由于调用其他命令会带来不小的开销,因此使用xargs可以显著提升操作速度。因为xargs能够尽量减少命令的调用次数,而不是每个文件都调用。
因此,上面的例子可以用下面的方案来处理怪异字符:
find . -name '*.mp3' -print0 | xargs -i -0 mv '{}' ~/songs
关于xargs命令的-i参数:mv命令需要将目标目录作为最后一个参数,而传统的xargs只是简单的获取输入,然后将其附加到指定命令的尾部,直到达到上限或处理完输入。但这样一来,mv命令肯定会报错。因此这里可以使用-i选项来指定输入参数的位置,默认使用{}作为替换字符串。但加入-i选项会导致对每个参数都要执行一次命令(-i选项无法实现参数分组),此外不是所有的xargs版本都支持-i选项。
-L:跟随符号链接查找文件(也可以使用-follow选项)
find -L . -name '*.mp3' -print0 | xargs -i -0 mv '{}' ~/songs
-iname:查找文件时不区分大小写
find . -follow -iname '*.mp3' -print0 | xargs -i -0 mv '{}' ~/songs
此外,find可以配合模式匹配来达到不区分大小写的目的,例:
find . -name '*.Jj[Gg]' -print
-mtime:按日期查找文件
find . -name '*.jpg' -mtime +90 -print
-mtime谓词接受一个参数用于指定要搜索的时间段。90代表90天。在数字前使用加号(+90)表明要搜索的文件是在90天已经修改的。使用减号(-90)表示文件是在90天内修改的。如果没有加减号,则表明正好是90天。
-type:按类型查找
find . -type d -name '*java' -print
类型说明:
b 块设备文件
c 字符设备文件
d 目录
p 管道(或fifo)
f 普通文件
l 符号链接
s 套接字
D 门(door)(仅限于Solaris)
-size:按大小查找文件
find . -size -3000k -print
-size谓词后面的数值参数前可以添加减号加号或者什么都不加,分别表示小于大于等于该数值。
按内容查找文件:如果需要在含有众多子目录的目录中查找含有特定内容的文件,可以使用以下方法:
find . -name '*.txt' -exec grep -Hi portend '{}' \;
说明:-H选项会输出包含搜索内容的文件名
逻辑运算:find还可以使用逻辑运算符AND、OR、NOT,如果知道文件的修改时间至少在一周前,但不超过14天,可以这样写查找语句:
find . -mtime +7 -a -mtime -14 -print
连续出现的两个谓词,其效果类似于逻辑AND,优先级高于OR。为了获得正确的优先级,可能还得使用括号。而括号在bash中有特殊含义,要在find中使用,需要对其转义。要么写作(和),要么放入单引号,写作'('和')'。
find . -mtime +14 -name '.txt' -o ( -mtime -14 -name '.txt' ) -print
说明:改语句查找的是修改时间在14天以前或14天以内的以txt结尾的文件。
locate与slocate:快速查找
locate与slocate会查询系统的数据库文件(通常由corn作业负责编译和更新),几乎瞬间就能找到文件或命令。(数据库的位置,会对什么对象进行索引、索引的频率都是由系统决定的。)
slocate保存了权限信息(以及文件名和路径),因此不会列出用户无权访问的文件。在大多数Linux系统中,locate只不过是指向slocate的符号链接。
-maxdepth:查找深度 距离当前目录最多X深度(层)的文件。
find / -maxdepth 5 -name '*.conf' | xargs grep listen
评论