find 命令_Linux下查找文件:find 命令

d1ec87859ebf88d7757b37e8d67602a4.png

find命令用于在指定目录中根据tests测试条件搜索符合tests测试条件的文件

概要

该命令的形式如下:

[-H

第一次看到该命令的人可能会被其复杂繁多的选项参数吓到。其实在日常开发中,很多选项并不多见。所以上述命令格式可以简化如下:

[path...

Path

即为查找文件的路径,命令将在指定目录及其子目录下进行查找文件,默认为当前路径

Expression

表达式,由option选项、test测试条件、action动作组成。option选项,均返回true。test测试条件即为当前文件的判定条件,其返回true/false;action动作是作用于当前文件的动作,其同样返回true/false。

如果在表达式中除了-prune外无其他action。则默认对整个表达式结果为true的文件执行 -print 动作,而不是直接在后面添加-print。 示例如下:

31cc43786411aa67a6b29041e289f47d.png

操作符

通常在表达式会包含多个option、test、action,如下代码 code 1 处所示。当未显式指定操作符时,默认为 "-a" (即AND)操作符,故其命令的完整形式为code 2处所示

'./subTest' -iname 

常用操作符如下:

  • expr1 -a expr2 : AND 逻辑与,使用短路求值。亦可写为expr1 -a expr2。如果 expr1 结果为 false,expr2 将不会被执行
  • expr1 -o expr2 : OR 逻辑或,使用短路求值。如果 expr1 结果为 true,expr2 将不会被执行
  • ( expr ) : 由于 AND 逻辑与的优先级 高于 OR 逻辑或的优先级。故,可以通过添加括号改变默认的操作符优先级。需要注意的是,命令中的左右括号需要使用反斜杠进行转义。即,( expr )
  • ! expr : NOT 逻辑非。对expr的结果进行取反

示例如下:

52eac2ede0d584700923b8ce0e94b209.png

Tests 测试条件

在日常开发中,tests 测试条件最为常用,现对常用的测试筛选项进行介绍:

根据文件名查找文件

根据文件名来查找文件,这也是日常最常用的:

# 大小写敏感
-iname <filename>   

其中,文件名参数可以使用Linux的文件名通配符,注意其不是正则

fa05ff6e861af8c6b7ddcba85ac2deda.png

根据文件权限

根据文件(Linux下,目录也属于文件)权限来筛选文件,其有3种匹配模式

# 严格匹配所给权限
    -perm -num      
  • 严格匹配

其将严格匹配所给权限的0和1设置,即结果文件的权限码必须和给定权限码num完全一致

-perm num

641f79cdea44375e06488f97c8023d1e.png
  • 满足所给全部权限位即可

对于给定权限码num,文件全部满足给定的权限位即可,对于多余的权限位并不敏感

-perm -num

8efee57a9f11967a0f032bc85e9b2821.png
  • 满足所给任一权限位即可

对于给定权限码num,文件若存在任一一个满足给定的权限位即可,对于多余的权限位并不敏感

-perm /num

fc81681d27167b09eb5fcd9362609af6.png

排除某个目录

查找文件时,如果已经知道某个目录下不存在我们所需文件,可以在find中指定排除,以免浪费时间搜索。下述命令中的-path test条件用来判定是否存在指定路径。如果是,则其返回true,并根据逻辑与的短路求值策略继续执行-prune action动作,用于排除该路径

    -path pathName -prune
    -path pathName -a -prune
  • 示例1

1处查看检索当前目录下所有的内容,而2处则是查看除subTest目录外的文件

d4c9473d7c04134c8760c0943124b686.png

相信这里会让人疑惑的地方在于 -print 前面的 -o 或操作符,根据前文所述,-path ./subTest -a -prune 用于排除指定目录,然后-print是查看剩下的文件,中间应该是用 -a 与操作符来连接啊。好,那我们先将上面代码中的 -o -print 改为 -a -print。来看看会发生什么

67c9e338cf083b862c2ba322d4a1a67b.png

咦?这里竟然输出的结果是不是让人很吃惊…………竟然是我们需要排除的目录。其实,问题是在于我们没有理清find命令的执行逻辑,find是对path下的所有文件(目录文件夹也是文件的一种)依次去执行表达式,根据test条件的结果来判定是否执行action。对于本例而言,当对subTest目录进行判定时,-path ./subTest 测试条件结果肯定为true,然后执行-prune以不对该目录下的文件进行遍历搜索测试,其是一个action且结果恒为真。如果此时后面如果是-a -print,则对当前测试的文件(即,subTest目录)执行打印动作,而遍历其他文件(比如,bers文件)进行测试时,-path ./subTest 测试条件结果为false,根据短路求值策略,均不会执行 -prune动作和-print动作,故最终我们看到的输出结果,只有./subTest目录文件;同理,如果后面是-o -print的话,测试 ./subTest 目录文件时,-path ./subTest -prune 结果为true,由于后面是-o 与操作符,根据短路求值策略,其将不会执行-print动作,而遍历其他文件(比如,bers文件)进行测试时,-path ./subTest 测试条件结果为false,根据短路求值策略,其将不会执行-prune动作,且 -path ./subTest -prune结果为false。而对于-print动作而言,由于其前面为 -o 或操作符,将会执行-print动作,即打印当前测试文件(比如,bers文件)

  • 示例2

按名查找并排除指定目录

16f1e9adbc34e552e0ac24700c64afb9.png

-a、-o 优先级

如前文所述,-a 与操作符优先级高于 -o 或操作符优先级。所以如果不注意这点,很容易会产生Bug。例如,我们期望找到名为 bers 或 numbers.txt 文件,代码如下:

710f60ec3a4bab80249c9b5a252c4821.png

从上文执行的结果,可以看到没有成功查找出bers文件,原因很简单,由于 -a 优先级比 -o 高,-print 动作只会在-iname 'numbers.txt' 测试条件返回true时执行。所以上述命令等价于下图所示

0e7f17db7c8ea95e14b5e3f4e08d5d72.png

同理,即使将numbers.txt换为一个不存在的文件名 abc ,也同样不会输出存在的bers文件

bf62491f64177260540c46bfebe15025.png

所以,对于该问题,需要通过添加括号来改变操作符的默认优先级,使其满足我们的需求

737f2590abc01a29fdc8e20edb942183.png
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值