这里介绍在Linux用于查找文件的find命令
概要
该命令的形式如下:
1 | find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression] |
第一次看到该命令的人可能会被其复杂繁多的选项参数吓到。其实在日常开发中,很多选项并不多见。所以上述命令格式可以简化如下:
1 | find [path...] [expression] |
Path
即为查找文件的路径,命令将在指定目录及其子目录下进行查找文件,默认为当前路径
Expression
表达式,由option选项、test测试条件、action动作组成。option选项,均返回true。test测试条件即为当前文件的判定条件,其返回true/false;action动作是作用于当前文件的动作,其同样返回true/false。
如果在表达式中除了-prune外无其他action。则默认对整个表达式结果为true的文件执行 -print 动作,而不是直接在后面添加-print。 示例如下:
操作符
通常在表达式会包含多个option、test、action,如下代码 code 1 处所示。当未显式指定操作符时,默认为 “-a” (即AND)操作符,故其命令的完整形式为code 2处所示
1 | find . -path './subTest' -iname "sub*"; # code 1 |
常用操作符如下:
- expr1 -a expr2 : AND 逻辑与,使用短路求值。亦可写为expr1 -a expr2。如果 expr1 结果为 false,expr2 将不会被执行
- expr1 -o expr2 : OR 逻辑或,使用短路求值。如果 expr1 结果为 true,expr2 将不会被执行
- ( expr ) : 由于 AND 逻辑与的优先级 高于 OR 逻辑或的优先级。故,可以通过添加括号改变默认的操作符优先级。需要注意的是,命令中的左右括号需要使用反斜杠进行转义。即,\ ( expr \ )
- ! expr : NOT 逻辑非。对expr的结果进行取反
示例如下:
如上所述,-a 与操作符优先级高于 -o 或操作符优先级。所以如果不注意这点,很容易会产生Bug。例如,我们期望找到名为 bers 或 numbers.txt 文件,代码如下:
从上文执行的结果,可以看到没有成功查找出bers文件,原因很简单,由于 -a 优先级比 -o 高,-print 动作只会在-iname ‘numbers.txt’ 测试条件返回true时执行。所以上述命令等价于下图所示
同理,即使将numbers.txt换为一个不存在的文件名 abc ,也同样不会输出存在的bers文件
所以,对于该问题,需要通过添加括号来改变操作符的默认优先级,使其满足我们的需求
Tests 测试条件
在日常开发中,tests 测试条件最为常用,现对常用的测试筛选项进行介绍:
根据文件名查找文件
根据文件名来查找文件,这也是日常最常用的:
1 | -name <filename> # 大小写敏感 |
其中,文件名参数可以使用Linux的文件名通配符,注意其不是正则
根据文件权限
根据文件(Linux下,目录也属于文件)权限来筛选文件,其有3种匹配模式
1 | -perm num # 严格匹配所给权限 |
严格匹配
其将严格匹配所给权限的0和1设置,即结果文件的权限码必须和给定权限码num完全一致
1 | -perm num |
满足所给全部权限位即可
对于给定权限码num,文件全部满足给定的权限位即可,对于多余的权限位并不敏感
1 | -perm -num |
满足所给任一权限位即可
对于给定权限码num,文件若存在任一一个满足给定的权限位即可,对于多余的权限位并不敏感
1 | -perm /num |
根据文件类型查找
通过-type选项指定文件类型进行查找,常见的文件类型如下:
- b : 块设备文件
- c : 字符设备文件
- d : 目录文件
- f : 一般普通文件
- l : 连接文件
- p : FIFO文件
- s : socket文件
测试结果如下:
根据文件所有者查找
通过-user选项按文件所有者进行查找,测试结果如下:
根据文件所有者的组查找
通过-group选项按文件所有者的组进行查找,测试结果如下:
根据文件大小查找
通过 -size 选项按文件大小进行查找,其选项使用说明如下:
1 | -size [-+] <sizeNum> [ckMGTP] |
文件大小数目sizeNum前的-、+分别表示小于、大于所指定文件大小,无符号则表示等于指定文件大小
ckMGTP 则分别表示文件大小的单位:分别表示字节、千字节、兆字节、吉字节、太字节、拍字节
测试结果如下:
Actions动作
-exec 动作
其可对find找到的文件执行其他命令,命令形式如下,其 {} 指代之前test测试条件等找到的文件名。;分号为该动作的结束符,其为Linux的特殊符号故其需要使用\进行转义
1 | -exec <command> {} ; |
测试结果如下: