find命令详解

系统版本:

[root@node1 ~]# cat /etc/redhat-release 
CentOS Linux release 7.1.1503 (Core) 
[root@node1 ~]# uname -r
3.10.0-229.el7.x86_64

find

实时查找工具,通过遍历指定起始路径下文件系统层级结构完成文件查找。

工作特性

  • 查找速度略慢
  • 精确查找
  • 实时查找

用法

find [OPTIONS] [查找起始路径] [查找条件] [处理动作]

  • 查找起始路径: 指定具体搜索目标起始路径,默认为当前目录
  • 查找条件: 指定的查找标准,可以根据文件名、大小、类型、从属关系、权限等等标准进行,默认为找出指定路径下的所有文件
  • 处理动作: 对符合查找条件的文件做出的操作,例如删除等操作,默认为输出至标准输出
     

查找条件:文件名


选项:

  • -name “pattern”: 查找文件名为“pattern”的文件
  • -iname “pattern”: 查找文件名为“pattern”的文件,不区分大小写

注:“pattern”支持glob风格的通配符,如:*,?,[],[^]

示例:

[root@node1 ~]# find /etc/ -iname "passwd"
#精确匹配查找文件名为“passwd”的文件,但不区分大小写
[root@node1 ~]# find /etc/ -iname "passwd*"
#查找以“passwd”开头的文件,不区分大小写

[root@node1 ~]# mkdir /etc/test
[root@node1 ~]# touch /etc/test/passwdx
[root@node1 ~]# find /etc -iname "passwd[[:alnum:]]"

 

查找条件:文件从属关系


选项:

  • -user USERNAME: 查找属主为指定用户的所有文件
  • -group GRPNAME: 查找属组为指定组的所有文件
  • -uid UID: 查找属主为指定的UID的所有文件
  • -gid GID: 查找属组为指定的GID的所有文件
  • -nouser: 查找没有属主的文件
  • -nogroup: 查找没有属组的文件

示例:

[root@node1 ~]# find /tmp/ -user moosefs
[root@node1 ~]# find /tmp/ -group moosefs
[root@node1 ~]# find /tmp/ -uid 3003
[root@node1 ~]# find /tmp/ -gid 3004

 

查找条件:文件类型


-type TYPE:

  • f: 普通文件
  • d: 目录文件
  • l: 符号链接文件
  • b: 块设备 文件
  • c: 字符设备文件
  • p: 管道文件
  • s: 套接字文件

示例:

[root@node1 ~]# find /dev -type b -ls
[root@node1 ~]# find /etc -type l -ls
#“-ls”表示“[处理动作]”

 

组合测试


  • 与: -a(默认组合逻辑)
  • 或: -o
  • 非: -not, !

示例:

[root@node1 ~]# find /tmp/ -nouser -type f -ls
or [root@node1 ~]# find /tmp/ -nouser -a -type f -ls
#必须符合两个条件“-nouser”和“-type f”

[root@node1 ~]# find /tmp/ -not -type f -ls
or [root@node1 ~]# find /tmp/ ! -type f -ls

[root@node1 ~]# find /tmp/ -not -user root -a -not -iname "*fstab*" -ls
or [root@node1 ~]# find /tmp/ -not ( -user root -o -iname "*fstab*" ) -ls
#找出/tmp目录下属主为非root,而且文件名不包含fstab字符串的文件
#第二种方式用括号括起来,原来的-a要改成-o,如果是-o,则要改成-a

 

查找条件:文件大小


-size [+|-]#UNIT
常用单位:K, M, G

  • #UNIT: (#-1, #],从所给值减1(不包含减了1的值)到所给值的区间
  • -#UNIT: [0,#-1],从0(包含0)到所给值减1的区间
  • +#UNIT: (#, ∞),从所给值(不包含该值)到无穷大
     

查找条件:时间戳


以“天”为单位的选项:

  • -atime
  • -mtime
  • -ctime

以“分钟”为单位的选项:

  • -amin
  • -mmin
  • -cmin

选项后面跟值:
-atime [+|-]#
注:把#看成负数,因为这里的时间指过去时

  • -#: (#, 0],从所给值开始(不包含所给值),到0(包含0值)
  • #: [#, #-1),从所给值开始,到所给值减1(不包含减了1的值)
  • +#: (oo, #-1],从所给值减1开始,到无穷久远

示例:

[root@node1 ~]# find /etc -atime +7 -ls
#查找7天之前访问过的文件
[root@node1 ~]# find /etc -mtime -1 -ls
#查找1天之内修改过的文件

 

查找条件:权限


-perm [/|-]mode

  • mode: 精确权限匹配
  • /mode: 任何一类用户(u,g,o)的权限中的任何一位(r,w,x)符合条件即满足,9位权限之间存在“或”关系
  • -mode: 每一类用户(u,g,o)的权限中的每一位(r,w,x)同时符合条件即满足,9位权限之间存在“与”关系

示例:

[root@node1 ~]# cd /tmp/
[root@node1 tmp]# touch a b c d e f g
[root@node1 tmp]# chmod 640 a
[root@node1 tmp]# chmod 666 b
[root@node1 tmp]# chmod 440 c
[root@node1 tmp]# chmod 775 d
[root@node1 tmp]# chmod 777 e

[root@node1 tmp]# find ./ -perm 644 -ls
#精确匹配查找权限为644的文件

[root@node1 tmp]# find ./ -perm /666 -ls
#至少有一类权限位有r或w(注意:这里是“或”),即符合条件
[root@node1 tmp]# find ./ -perm /111 -ls
#至少有一类权限位有x,即符合条件
[root@node1 tmp]# find ./ -perm /002 -ls
#不看属主和属组权限,匹配其他用户包含w权限的文件
#其他用户具有w权限的文件危险性很高,一般不设定其他用户具有w权限
[root@node1 tmp]# find ./ -perm -002 -ls
#这个结果和上面一条相同,因为忽略属主和属组部分
[root@node1 tmp]# find ./ -perm /022 -ls
#只要属组和其他用户当中,有一类有w权限,即匹配
[root@node1 tmp]# find ./ -perm -022 -ls
#属组和其他用户必须同时拥有w权限的文件

[root@node1 tmp]# find ./ -perm /222 -ls
#至少有一类权限位有w,即符合条件
[root@node1 tmp]# find ./ -not -perm /222 -ls
#任何用户都没有w,即符合条件

[root@node1 tmp]# find ./ -perm -222 -ls
#匹配所有用户都有w权限的文件
[root@node1 tmp]# find ./ -not -perm -222 -ls
#匹配至少有一类用户没有w权限的文件

#至少有一类用户有权限的反义:任何用户都没有权限
#所有用户都有权限的反义:至少有一类用户没有权限

 

处理动作


  • -print: 输出至标准输出(默认动作)
  • -ls: 类似于对查找到的文件执行“ls -l”命令,输出文件的详细信息
  • -delete: 删除查找到的文件
  • -fls /PATH/TO/SOMEFILE: 把查找到的所有文件的长格式信息保存至指定文件中
  • -ok COMMAND {} ;: 对查找到的每个文件执行由COMMAND表示的命令,每次操作都由用户进行确认
  • -exec COMMAND {} ;: 对查找到的每个文件执行由COMMAND表示的命令

示例:

[root@node1 tmp]# useradd centos
[root@node1 tmp]# chown centos:centos c e
[root@node1 tmp]# userdel -r centos
[root@node1 tmp]# find ./ -nouser -a -nogroup
#查找没有属主也没有属组的文件
[root@node1 tmp]# find ./ -nouser -a -nogroup -ok chown root:root {} ;
#将没有属主也没有属组的文件,属主和属组都改为root

[root@node1 tmp]# find ./ -perm /002 -exec mv {} {}.danger ;
#将其他用户具有w权限的文件改名加上danger标记

 

xargs


在使用 find命令的-exec选项处理匹配到的文件时, find命令将所有匹配到的文件一起传递给exec执行。但有些系统对能够传递给exec的命令长度有限制,这样在find命令运行几分钟之后,就会出现溢出错误。错误信息通常是“参数列太长”或“参数列溢出”。这就是xargs命令的用处所在,特别是与find命令一起使用。

xargs从find命令接收并传递参数,配合管道符|来使用,把find命令的stdout作为自己的stdin,再转换成command line形式的参数传给其它命令。
 
语法:

find [options] | xargs [options] [TargetCommand [options]]

选项:

  • -l1: 一次传递一行给后面的命令(默认为一行)
  • -t: 处理之前打印出命令
  • -i: 用{}替代stdin获取的数据
  • -I []: 用[]或其它符号替代从stdin获取的数据(-l后面必须跟替代符号)
  • -p: 提示是否执行后面的命令,y执行,n不执行

示例:

[root@node1 ~]# find . -type f -name "*.log" -print0 | xargs -0 rm -f
# 将当前目录下以“.log”结尾的普通文件删除
# xargs解决/bin/rm Argument list too long的问题

# “-print0”和“xargs -0”,xargs默认以空白字符(空格,TAB,换行符)来分割记录,
# 假如find得到的文件名中含有空格,xargs将不能正常处理;
# 因此,“-print0”表示让find在打印出一个文件名之后,接着输出一个NULL字符“”,
# xargs后面的“-0”则告诉xargs也使用NULL字符作为分隔符,
# 这样就解决了xargs不能正常处理含有空格的文件名的问题

[root@node1 ~]# find . -perm -7 -print | xargs chmod o-w
# 在当前目录下查找其他用户具有rwx权限的文件,并收回相应的w权限

[root@node1 ~]# find . -type f -atime +0 -print0 | xargs -0 -l1 -t rm -f
# 将当前目录下在24小时之前(包含24小时)访问过的普通文件删除

[root@node1 ~]# find . -name "*.log" | xargs -p -i mv {} test4
or [root@node1 ~]# find . -name "*.log" | xargs -p -I [] mv [] test4
# 将当前目录下以“.log”结尾的文件移动到“test4”目录

 
 

发表评论

邮箱地址不会被公开。