一、find简介
find命令是linux系统下一个强大的文件查找命令,它可以根据你所指定的文件大小、权限,属主、属组、修改时间、访问时间等条件查到你想要得到的东西。
谈到find,有人可能就会与grep命令纠结一会儿,grep命令主要是文本内容查找,在文件范围内找符合条件的文本;而find命令则是在系统范围内找符合条件的文件,它不关心文件的内容,只关心文件是否存在。所以,find是针对文件的而grep是针对文本内容的。grep另一种用法就是使用管道命令来接收前一个命令的输出来做为自己的输入,这则是用来匹配字符串的。
二、find命令语法结构
find [查找路径] [查找条件] [处理动作]
查找路径:默认为当前目录
查找条件:默认为查找指定路径下的所有文件
处理动作:默认为显示
从find命令的语法结构也可以看出,它的几个选项都是可选的,如果不选的话,则会列出当前目录下的所有文件。
三、find命令功能使用
1)查找条件
-name 文件名称,支持使用globbing文件通配。
-inme,查找时不区分大小写。
*,?,[],[^],\(\)(转义)
例:查找/usr/local下所有包含httpd的文件
全用-iname选项后,就会忽略大小写,并且find会递归整个查找路径下的目录和文件。
-user UserName:根据属主查找
-group UserName:根据属组查找
-nouser:查找没有属主的文件
-nogroup:查找没有属组的文件
例:找出/usr/local下属主是nmshuishui的文件
-uid UID:根据指定的UID查找
-gid GID: 根据指定的GID查找
既然有了根据用户名查找,为什么还要来一个UID和GID呢?如果你删除了一个账户,但是没有使用-r选项,因此你删除的账户是没有完全删干净的。
例:查找/usr/local下属于UID508的所有文件
2)组合条件
-a:与,and,同时满足。多个条件与时,-a可省略
-o:或,or
-not,!:非,取反
例:找出/usr/local下属主是nmshuishui且属组是root的文件
例:找出/usr/local/httpd下不属于root或vbird的所有文件
上题所说的不属于root或vird实际上是指既不属于root又不属于vbird的所有文件,逻辑问题,自己理解。
3)-type
根据文件类型查找
f:普通文件 d:目录 b:块设备 c:字符设备 l:符号链接文件 p:命令管道 s:套接字
例:查找/usr/local下属主是nmshuishui的目录。
4)-size
根据文件大小查找
-size [+|-]#
常用单位:K,M,G
这里的size就是中国移动的做法了,通话没有一分钟就是一分钟了。如果-seze 1M,就代表是大于0M大而小于1M的,-size -1M就代表是0M到0M以下的,那-size +1M就是1M以上的了,有点不符合常理。
例:找出/etc/下大于1M且文件类型为普通文件的所有文件
5)根据时间戳查找
以天为单位(time)
-atime[+|-]:access,访问时间 〡 +:表示(#+1)天之外被访问过
-mtime:modify,修改时间 →〡 -:表示(#)天之内被访问过
-ctime:create,改变时间 〡无:表示 # --(#+1)天的时间段被访问过
以分钟为单位(min)
-amin[+|]
-mmin
-cmin
如上图,-2天其实就是2天之内的,2天就是2天到3天的,+2天就是3天之外的,这回应该更好理解点儿了吧。
例:查找当前系统上没有属主或属组,且最近1个月内曾被访问过的文件。
6)根据权限查找
-perm [+|-]mode
mode:精确匹配 无符号,精确匹配
+mode:满足任何一类用户的任何一位权限即可 +号,或关系,范围大
-mode:每类用户的任何一位都需匹配 -号,且关系,范围小
说明:+mode:常用于查找某类用户的某特定权限是否存在
例:查找/etc目录下所有用户都没有写权限的文件
所有都没有,相反:任何一个有
所有都有,相反:至少有一个没有
例:查找/usr/local/share/目录下至少有一类用户没有写权限(都有,取反:到少一个没有)
例:查找/usr/local/目录下,所有用户都有执行权限且其它用户有写权限的文件
find /usr/local -perm -111 -a -perm -002 = find /usr/local -perm -113
四、处理动作,默认为-print
-print:打印在标准输出上
-l:以长格式输出各文件信息
find /tmp -perm -006 -ls ls是处理动作
-exec COMMAND {} \;
对查找到的文件执行指定的命令({}表示占位符,表示接收来自前面的find命令所查找到的文件,并对那个文件执行相应操作.)
|xargs COMMAND
五、-exec与|xargs COMMAND对比
find把查找到的所有文件一次性传递给-exec所指定的命令,如果同时传递的文件过多,由于参数过多,会导致命令溢出,所以为了避免这种情况发生,我们还需要使用find |xargs COMMAND 这个命令,因为这个命令是把前面命令所执行的结果当作后面命令的参数使用的,xargs是一批批接受命令,所以不会由于传递参数过多而导致溢出的结果.
既然这样,是不是我们再也不需要使用find 后面跟\;这种机制了?还要-exec干什么?因为还有一种情况是xargs所搞不定的,那就是我们要给一类文件进行统一改名.
mv `find /tmp -iname "*.doc" XXX(*.docx?),像下例中,你使用mv能统一改吗?目标怎么命令啊?难道要来一个*.docx吗?*是什么啊?看来还是没法搞定,这样,我们的那个-exec中的{}占位符就派上用场了,前面怎么占位,后面就怎么输出,统一改名so easy。
find /tmp -perm -664 -type f -exec chmodo+x {} \; 把前面找到的文件放到{}中,进行统一权限修改
find /tmp -perm -664 -type f |xargs chmodo+x 相当于把前面找到的文件通过管道输出给xargs作为参数,再进行统一权限修改