Linux学习(二) --- 功能强大之find

本文详细介绍了Linux中find命令的使用,包括文件名匹配、正则表达式、路径操作、逻辑运算符、时间戳筛选、权限检查、文件类型判断、大小过滤、用户和用户组查询以及输出格式和执行外部命令等各个方面,是学习和掌握find命令的全面指南。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

find之强大毋庸置疑,此处只是带领大家一窥find门径,更详细的说明见man  find和 info find。
整篇文章循序渐进,从最常用的文件名测试项开始步步深入,到第六节基本讲完find处理文件的规则,再之后的章节是一些常用表达式的说明。
(此篇中所有选项及例子基于GNU find version 4.2.28)

(一)Get Start

最简单的find用法莫过于如此:
$ find  .
查找当前目录下的所有文件。
find命令的一般格式为:
find [ - H] [ - L] [ - P] [path ... ] [expression]

其中,'-H' '-L' '-P'三个选项主要是用来处理符号连接,'-H'表示只跟随命令行中指定的符号连接,'-L'表示跟随所有的符号连接,'-P'是默认的选项,表示不跟随符号连接。
例如,在我的当前目录下有一个符号连接e1000,现在我想查找文件名中最后一个字母是数字的源文件,那么
$ find  - .   - name  " *[0-9].c "   - print
./ 2234 . c
像上面这样写只能查找出当前目录下符合要求的文件,却找不出e1000下的文件。因此可以这么写:
$ find  - H e1000  .   - name  " *[0-9].c "   - print
或者使用 '-L'选项
$ find  - .   - name  " *[0-9].c "   - print

格式中的 [path... ]部分表示以此目录为根目录进行搜索。

格式中的 [expression]是一个表达式。 最基本的表达式 分为三类:设置项(option)、测试项(test)、动作项(action),这三类又可以通过逻辑运算符(operator)组合在一起形成更大更复杂的表达式。设置项(如-depth,-maxdepth等)针对这次查找任务,而不是仅仅针对某一个文件,设置项总是返回true;测试项(test)则不同,它针对具体的一个文件进行匹配测试,如-name,-num,-user等,返回true或者false;动作项(action)则是对某一个文件进行某种动作(最常见的如-print),返回true或者false。
正是[expression]部分的丰富,才使得find如此强大。此部分较复杂,后面慢慢说明。


(二)文件名

根据文件名来查找一个文件是大家经常遇到的事情,第一节中的'-name'正是解决此问题的。
-name属于表达式中的测试项(test),它按照文件名模式来匹配文件,若匹配则返回true,否则返回false。最好用引号将文件名模式引起来,防止shell自己解析要匹配的字符串。(可以用单引号也可以用双引号,单引号和双引号在shell环境中的区别见后续部分)
例如,想要的当前目录及子目录中查找文件名以一个大写字母开头或者以小写a或b开头的文件,可以用:
$ find  .   - name  " [A-Za-b]* "   - print
./ a_book_of_c . chm
./ TMP1234
如果想在当前目录查找文件名不以大写字母开头,之后跟一个小写字母,再之后是两个数字,最后是.txt的文件,可以这么用:
$ find  .   - name  " [^A-Z][a-z][0-9][0-9].txt "   - print
./ @y38 . txt
注意:此处的模式匹配并不符合正则表达式。


-name对大小写字母敏感,如果想匹配时不考虑大小写可以使用-iname测试项。'i'可以加在许多选项前面,比如-ipath,-iregex,-iwholename等等,都是表示大小写不敏感。


(三)正则表达式

使用上面的-name测试项能解决许多问题,但是有些还是不太好办,比如:查找当前目录下名称全部为数字的c源代码文件,这时就该'-regex'出手了。正则表达式绝对值得你去好好研究一下,在unix系统下太有用了,这里不做过多说明,请读者自行学习。
-regex同样属于测试项。使用-regex时有一点要注意:-regex不是匹配文件名,而是匹配完整的文件名(包括路径)。例如,当前目录下有一个文件"abar9",如果你用"ab.*9"来匹配,将查找不到任何结果,正确的方法是使用".*ab.*9"或者".*/ab.*9"来匹配。
针对上面的那个查找c代码的问题,可以这么写:
$ find  .   - regex  " .*/[0-9]*/.c "   - print
./ 2234 . c

还有一个设置项(option)'-regextype',可以让你根据自己的喜好选择使用的正则表达式类型,大家可以试试。


(四)wholename与path

既然上一节提到了完整文件名(包括路径名),那么这里不妨说一下-wholename和-path。
-wholename和-path都属于测试项(test),而且功能也一样。-path从字面上看给人一种错觉,好像只匹配路径名(或者目录名),其实它也可以匹配文件名,因此-wholename这个名字更贴切一些。
看看这个例子,当前目录下有一个phone目录,phone目录里有一个文件名称是puk.txt,使用-path:
$ find  .   - path  ' *phone/pu* '
./ phone / puk . txt

另外要提一点:使用-path的一般格式是:find [path ...] -path pattern ...
它的意思是:在[path ...]部分指明的路径上,使用pattern匹配所有文件的完整文件名;而不是说在类似的pattern目录下查找文件


(五)逻辑运算符

有了上面三个选项,你现在应该对文件名的相关匹配得心应手了,对于不是很复杂的查找应该也胜任了。但是看看这个例子,解释一下它在做什么?
$ find . -size +0c -wholename "*e*[0-9]
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值