find
find命令号称"Linux 中最强大的命令"(某柱语)自然有他的强大之处。find命令是一个实时性的命令,为什么叫实时性命令呢?那是相对于locate命令说的。大家不要觉得locate命令很快就觉得它很嚣张。locate在背地里是做了很多准备的,它有自己的数据库,通过crontab默默的建立索引。如果有个文件在locate建立索引之后创建,那么你是没有办法立即通过locate来查找的,因为它数据库里面没有。find作为实时性的命令,虽然慢了点,但他的结果都是实时的,他所说的都是真诚的。下面就详细介绍下这个最强男人命令。
命令格式
find 路径名 -选项 [-print -exec -ok ...]
路径名是我们要查找的路径,就是给find大展拳脚的地方。
选项是精髓,通过不同选项让find通过不同的方式达到不同的查询效果。例如,我们看到的-print,就是将查询结果打印出来。-exec就是将find出来的结果整体(holistic)的送给-exec后面接的命令操作。这些选项几乎是不冲突的,可以同时使用。
常用选项
-name
name可以说是find最好的搅基伙伴,他们总是形影相随,其中必有内幕。在name选项后面的参数需要加上引号,注意是双引号,两层更安全。
现在我们的情况如下
[root@zhaowei test]# ll total 0 -rw-r--r-- 1 root root 0 Feb 27 13:41 a.a -rw-r--r-- 1 root root 0 Feb 27 13:41 a.b -rw-r--r-- 1 root root 0 Feb 27 13:41 a.c -rw-r--r-- 1 root root 0 Feb 27 13:41 a.d -rw-r--r-- 1 root root 0 Feb 27 13:41 a.e -rw-r--r-- 1 root root 0 Feb 27 13:41 b.a -rw-r--r-- 1 root root 0 Feb 27 13:42 c.a -rw-r--r-- 1 root root 0 Feb 27 13:42 d.a -rw-r--r-- 1 root root 0 Feb 27 13:42 e.a [root@zhaowei test]# find . -name "*.a" ./c.a ./e.a ./b.a ./d.a ./a.a |
这个例子表明我们可以通过通配符来模糊搜索,这只是冰上一角,再看下图。
[root@zhaowei test]# find . -name "[a-c].*" ./a.d ./c.a ./a.b ./a.e ./a.c ./b.a ./a.a |
厉害吧,是不是想到了RE呢,哈哈,他们同样是很有基情的哦。
-perm
按照权限来查找,实例如下
[root@zhaowei test]# ll total 0 -rw-r--r-- 1 root root 0 Feb 26 11:08 a[1-5] -rw-r--r-- 1 root root 0 Feb 26 11:08 a[1-5].a -rw-r--r-- 1 root root 0 Feb 26 11:08 a.a -rwxr--r-- 1 root root 0 Feb 26 11:08 a.b -rw-r--r-- 1 root root 0 Feb 26 11:08 a.c -rw-r--r-- 1 root root 0 Feb 26 11:08 a.d -rw-r--r-- 1 root root 0 Feb 26 11:08 b.d -rw-r--r-- 1 root root 0 Feb 26 11:08 c.d -rw-r--r-- 1 root root 0 Feb 26 11:08 e.d [root@zhaowei test]# find ./ -perm 744 ./a.b
|
我们可以看到,find命令成功的找到了唯一的一个权限掩码(我原创的名字,大家知道就行了)为744的文件,就是a.b。
-prune
熟悉英语的朋友们都知道这个单词是裁剪的意思,那它到底起到什么作用呢,多说无疑,还是看实例吧。
先来基本的例子,-prune和 -path可以是基情的一对,他们相互配合,可以避开一些目录,裁剪搜索树的某些分支。
[root@zhaowei test]# tree . |-- a | |-- a.a | '-- b.b |-- a.a '-- b.b
1 directory, 4 files [root@zhaowei test]# find . -path "./a" -prune -o -print . ./b.b ./a.a |
这里我们看到的是我们忽略了所有./a下的文件。比较值得注意的是-prune -o -print这个组合,现在讲起来比较麻烦。-o的意思是短路求值,意思相当于||。举个例子。
-path "/a" -o -path "/b" |
这个是什么意思呢,就是下面。
path == "/a" || path == "/b" |
我们知道在C语言里面,如果前一个表达式的值为真,则后面的表达式就不再进行判断。通过这样一个关系,我们可以简单的实现一些蕴含在命令里的判断语句。比如:
-path "/a" -a -prune -o -print |
我们分析下这个句子,首先如果我们进入了/a这个目录,也就是说第一个表达式的值为真,这个时候由于-a的存在我们需要去判断-a后面的-prune,这样/a目录就被裁减了,prune语句的值为真,那么前面两个句子的值就为真,对于-o就会不再判断print语句的真假。print就不会打印出来。
现在分析一个高级的例子。
这例子使用了两个prune。一般来说-a是可以省略的。反斜杠是用来转义,告诉shell,这是我的地盘,你不用处理它。我们可以在任意的两个没有-o的选项中加一个-a,然后慢慢的去分析理解。
下面是一个单独使用的例子。
没有使用prune选项的时候我们得到这个效果
[root@zhaowei d]# tree . |-- a.b '-- d '-- d
2 directories, 1 file [root@zhaowei d]# find . -name d ./d ./d/d |
在使用prune选项的时候我们得到另一个结果
[root@zhaowei d]# tree . |-- a.b '-- d '-- d
2 directories, 1 file [root@zhaowei d]# find . -name d -prune ./d |
明白了吧,prune的效果之一是当我们查找的目标为一个目录时,find命令将不把它作为目录在接着查下去,用英语讲就是do not descend into it。
-user
按照文件属主来查找文件。
-group
按照文件所属的组来查找文件。
这两个选项很傻瓜,你们自己试一下就知道了。
-mtime -n +n
按照文件的更改(modified time)时间来查找文件,-n表示文件更改时间距现在n天以内,+n表示文件更改时间距现在n天以前。这个命令和atime,ctime差不多。其中atime是指access time,ctime是指changed time。值得注意的是他们的单位都是24小时,这个是和"天"有点区别的。
-nogroup
查找属于非法用户组的文件。也就是没有在/etc/group中登记过的黑户口。
-nouser
查找属于非法用户的文件,也是黑户口。
嗯,这两个是垃圾清理选项。可以设定在crontab里面进行定时的清理。
-newer file1
这个选项使find命令可以查找出比file1新的文件。
-type
查找指定类型的文件,如下:
b - 块设备文件。
d - 目录。
c - 字符设备文件。
p - 管道文件。
l - 符号链接文件。
f - 普通文件。
这里要强调的是Linux下面是没有后缀名的概念的,不会通过后缀名判断文件的类型。
-size n[c]
查找文件长度为n块的文件,带有c时表示文件长度以字节计。
[root@zhaowei test]# ll total 8 -rw-r--r-- 1 root root 2 Feb 26 12:21 1 -rw-r--r-- 1 root root 0 Feb 26 12:17 2 [root@zhaowei test]# find . -size 2c ./1 |
其他
-depth
在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。这个选项可以将之前的-prune选项屏蔽掉。
-fstype
查找位于某一类型文件系统中的文件,这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。
-mount
只在该文件系统内查找。
-follow
对于符号链接,只显示其实际文件
强大之处
find的强大不但源于自身,更是源于他可以借助于别人的力量完成自己的事情。这种借助就是通过exec实现的,当然xargs不会吃醋,xargs能力更强,完全没必要有想法。
我们将想要执行的命令放在exec后面(赶走你脑子里那些混乱的概念吧,exec,fork,cow等等),然后是一个{},最后以/;结尾,这个要切记。还有要注意的一点是记住将find的结果打印出来-print,这样后面的命令才能使用它们作为参数。废话不多说,上例子吧。
查找所有普通文件并且删除它们
[root@zhaowei test]# ls a.a a.b a.c a.d b.d c.d d.d [root@zhaowei test]# find . -type f -exec rm {} /; [root@zhaowei test]# ls [root@zhaowei test]# |
看着很强大,但会不会强大到"打击低俗网站专项行动"的程度呢?就是出现误删文件的情况。为了避免这种情况,find很体贴的给大家准备了安全模式,就是在执行rm这样可能自宫的命令时进行提示,你确定吗?(王小丫)这种安全模式就是-ok
大家再看一个例子
[root@zhaowei test]# ls a.a a.b [root@zhaowei test]# find . -type f -ok rm {} /; < rm ... ./a.b > ? y < rm ... ./a.a > ? y [root@zhaowei test]# ls [root@zhaowei test]# |
看到了吧,精确制导。这么强大的兵器,如果遇到了grep会发生什么事情呢?那就是 更强大!
好吧,如果你只记得一部分文件名和一部分内容的话,没关系,也可以用find找到你需要的文本。下面就是例子
[root@zhaowei test]# ls 1111 aaaa [root@zhaowei test]# cat 1111 1234 [root@zhaowei test]# cat aaaa abcd [root@zhaowei test]# find . -name "*a" -exec grep "ab*" {} /; abcd [root@zhaowei test]# |
你会了吗?
1、查找当前用户主目录下的所有文件
2、让当前目录中文件属主具有读、写权限,并且文件所属组的用户和其他用户具有读权限的文件
3、为了查找系统中所有文件长度为0的普通文件,并列出它们的完整路径
4、查找/var/logs目录中更改时间在7日以前的普通文件,并在删除之前询问它们
5、为了查找系统中所有属于root组的文件
6、find命令将删除当目录中访问时间在7日以来、含有数字后缀的admin.log文件
7、为了查找当前文件系统中的所有目录并排序
8、为了查找系统中所有的rmt磁带设备
参考答案
1.
$ find $HOME -print
$ find ~ -print
2.
$ find . -type f -perm 644 -exec ls -l { } /;
3.
$ find / -type f -size 0 -exec ls -l { } /;
4.
$ find /var/logs -type f -mtime +7 -ok rm { } /;
5.
$find . -group root -exec ls -l { } /;
-rw-r--r-- 1 root root 595 10月 31 01:09 ./fie1
6.
$ find . -name "admin.log[0-9][0-9][0-9]" -atime -7 -ok
rm { } /;
< rm ... ./admin.log001 > ? n
< rm ... ./admin.log002 > ? n
< rm ... ./admin.log042 > ? n
< rm ... ./admin.log942 > ? n
7.
$ find . -type d | sort
更多推荐
linux系统find命令一些用法,没有xargs的
发布评论