我们知道在Windows下的查找,可以按很多中方式,比如,按文件名(我们平时一般都是用这个),按修改日期、按大小。其实,这些功能,Linux的find命令都是有的。其实,find命令的参数就是用来指明查找条件的。(这些条件参数都是用-开头的)。find 命令可以按文件名(-name),文件的大小(-size)、文件的修改时间(-mtime)、文件的类型(-type)等条件查找。
当然,查找肯定是需要路径的,假如不指定路径的话,find命令默认使用当前路径(即当前目录)。
find 命令的一般操作为
find path-option xxxx
-option就是上面的按什么查找。
按照文件名查找:
用-name 作为参数指明
比如,我们按照名字查找test.c文件
$find . -name test.c
命令中的,find后面的点号就是查找路径。查找路径是作为第一个参数。而参数-name 则指定了查找方式,此时是按照文件名查找。最后的test.c表示要查找的文件名。
很自然会想到:文件名能不能使用通配符? 当然是可以的。不过,要使用””括住。比如查找所有的.c文件:
$find . -name “*.c”
find 命令除了可以查找所有的.c文件外,还可以找出所有的非.c文件。
$find . ! –name “*.c”
就是在 -name 的前面加上 C语言的 ! 操作符即可。!和-name之间有空格
find 命令还可以同时找两类的文件。
$find . \(-name “*.cpp” -o -name “*.c” \)
其中,-o表示或者,而\( \)的作用就是把里面的两个查找条件看作一个整体。这是一个很强大的功能。很容易由-o表示or想到: -a表示and。
另外,选项-iname 则是不区分大小写的情况下按照文件名查找。
按照时间查找:
有三种时间,修改时间(-mtime),访问时间(-atime),文件属性改变时间(-ctime).并没有创建时间的。
比如想查找3天内修改过的文件
$find . -mtime -3
而找三天之前修改过的文件为
$find . -mtime +3
-n表示多少天之内,+n 表示多少天之前。
天这个时间粒度比较大,所以还有另外一组粒度比较小的查找条件参数。
-mmin -amin-cmin 时间粒度是分钟。用法一样。
另外,find命令提供的一个-newer查找条件。明显是一个比较级,所以需要一个参照物。它是指修改时间,不是访问时间。
$find . -newer test.c
表示,比test.c文件还要晚修改的文件。是不是有点绕不过来了,呵呵。想一下英语里的最新的新闻怎么说的。Lastest news.最后的才是最新的。所以newer(更新的)自然是晚一些修改的文件。
说一下那个-ctime 这个是指文件属性修改时间。文件属性指的是文件所有者、访问权限这些东西。
按照文件类型查找:
用-type 作为参数指明
文件类型有下面这些,具体就不解释了,可以参照《Unix环境高级编程》
$find . -type f 表示查找普遍文件
按照文件大小查找:
用-size作为参数指明。
和时间相似,有大于,小于,等于某个值。比如,大于用+、小于用-,等于什么都不用。
比如查找大于2k的文件: $find . -size +2k
等于2M就用$find . -size 2M
其实,按大小查还是比较简单的。不过有两点要特别说明一下。
大小粒度(单位)有:
b 块(即512字节)
c 字节
w 双字(即2字节)
k 平常的KB
M 平常的MB
G 平常的GB
最后两个是大写,前面的都是小写。Linux是大小写敏感的,所以不能写错。
另外一个需要注意的地方是,在我的机器里Ubuntu10.04。使用k这个粒度时,会出现向上取整的情况。就是说,小于1k的,都是算1k。大于1k而小于2k的都是算2k。比如说,假如查找大小等于1k的文件时,那么那些小于1k的文件都是满足条件的。这个特点很奇怪。
同样,M、G都是有这种情况。而c w b都没有这样的情况。
按照文件的属主来查:
使用-user 作为参数
比如$find . -user root 查找属主是root的文件。
同样地,可以按照属主所在的组来查。
使用-group作为参数。
比如$find . -group root
按照文件权限查找:
使用参数-perm
文件权限是指属主、属主的组、other对文件拥有的可读、可写、可执行权限。
比如$find . -perm 755
在路径中查找:
使用-path作为参数
有时,我们不一定查找文件,还可能查找一个目录
比如,要查找是不是存在一个叫test的目录或者文件
$find . -path “*test*”
之所以用通配符,是因为这是在路径中查找,路径中,是会包含其他字符的。比如上面的查找结果为./test这就包含了前面的./字符
在用这个参数时,会发现,其实find命令默认情况下是会递归查找子目录的。这就引出了下面那个参数。
限定查找层次:
使用-maxdepth -mindepth
有时,我们只想在当前目录查找,或者只挖地三尺,第四尺就不挖了。那么就find命令的默认递归查找子目录就不能满足我们的需求了。
-maxdepth 表示只挖到第几层,-mindepth表示从第几层开始挖起。其中,1 都是表示当前目录。
比如,$find . -maxdepth 3 -name test
表示从当前目录开始搜索,只搜索到孙子目录。
-maxdepth 和 -mindepth 是可以配合使用的。
$find . -mindepth 2 -maxdepth 4 -name test
表示从子目录开始查找,只查找到曾孙目录。
需要注意的是:查找层次这个参数要放到查找目录的后(假如使用默认目录,就放到find的后面,作为第一个参数)。
使用正则表达式查找:
使用-regex作为参数
同-path一样,这个参数是用来查找一个路径的。不过,使用正则表达式来匹配而已。
附加功能:
find命令除了查找文件外,还能对查找出来的文件进行一些操作。
用-delete删除查找到的文件。
编辑文件时会产生一些 以~结尾的文件名。这时,可以用下面的命令,方便地删除:
$find . –name “*~” –delete
除了-delete外,还可以使用强大的-exec参数。
-exec参数可以接Linux的其他命令。
格式为 -exec command {} \;
command是具体的Linux命令。后面的{}对应每一个匹配的查找结果都替换成对应的文件名。大括号中间不能有空格。大括号和后面的\要有空格,而\和后面的分号则没有空格。
$find . -maxdepth 1 -name “*.cpp” -exec cat {} \;
把当前目录下的.cpp文件的内容都连接在一起,然后输出。
如果想将内容重定向到一个文件里面可以用
$find . -maxdepth 1 -name “*.cpp” -exec cat {} \; >a.txt
-exec后面只可以接一个命令。不过,可以用另外一招,使得其执行多个命令。
我们先把多个命令写到一个脚本文件com.sh中,然后执行
$find . -maxdepth 1 -name “*.cpp” -exec ./com.sh {} \;
有一个和-exec相似的参数-ok,它在操作前会询问用户。
参数化搜索到的文件名:
直接使用命令 $find . -name "*.cpp" | cat | wc -l",那么将无法正确统计.cpp文件的行数。因为搜索出来的内容(即文件名),经过管道符后,作为cat标准输入中的字符串了,而不是作为cat命令的参数。明显,很多时候我们更想使得搜索出来的文件名作为另外一个命令的参数,而非标准输入中的字符串。此时,可以使用命令 xargs,它呐能够把标准输入中的字符串拆成一个个的参数,并将这些参数作为另外一个命令的参数。所以,如果想统计当前目录以及其子目录的所有cpp文件的行数,可以使用命令 $find . -name "*.cpp" | xargs cat | wc -l
参考文献:《Linux Shell脚本攻略》