find命令是linux下最常用的一个命令,它可以根据文件名、文件属性、类型、大小、时间戳等来实时查找你需要的文件,并可针对搜索结果进行处理。
语法:find [查找路径] [查找条件] [处理动作]
查找路径:默认为当前目录
查找条件:默认为指定路径 下的所有文件
处理动作:默认显示至屏幕
一、查找条件
1.按文件名称查找
-name “文件名称“ 支持使用globbing字符
[root@test ~]$find /tmp -name 'test*' /tmp/test.conf
-iname 按文件名称查找,忽略大小写
[root@test ~]$find /tmp -iname 'test*' /tmp/test.conf /tmp/TEST.conf
2.按文件属性查找
-user 或 -group 根据文件的属主或属组查找
[root@test ~]$find /tmp/ -user 'mysql' /tmp/mysql.sock
-uid 或 -gid 根据uid或gid查找
[root@test ~]$find /tmp/ -uid 27 -ls 9961483 0 srwxrwxrwx 1 mysql mysql 0 May 26 13:37 /tmp/mysql.sock
nouser 或 nogroup 删除user时文件属主则为uid,也就是nouser,nogroup同理。
[root@test ~]$ find /tmp/ -nouser -ls 9961486 0 -rw-r--r-- 1 608 608 0 Jun 20 16:56 /tmp/TEST.conf
3.按组合条件查找
与 -a 默认支持可省略
或 -o
非 -not ! 条件取反
-not A -a not B = -not (A -o B)
-not A -o not B = -not (A -a B)
4.-type : 根据文件类型查找
f :普通文件
[root@test ~]$find /soft/ -maxdepth 1 -type f -ls 2228226 448 -rw-r--r-- 1 root root 458372 Apr 4 03:08 /soft/keepalived-1.2.20.tar.gz
d:目录
[root@test ~]$find /soft/ -maxdepth 1 -type d -ls 2228225 4 drwxr-xr-x 3 root root 4096 Apr 9 12:41 /soft/ 2228227 4 drwxrwxr-x 7 magedu magedu 4096 Apr 9 12:43 /soft/keepalived-1.2.20
l :符号链接
[root@test ~]$find /etc -maxdepth 1 -name "redhat*" -type l -ls 4719157 0 lrwxrwxrwx 1 root root 14 Aug 26 2015 /etc/redhat-release -> centos-release
b:块设备
c:字符设备
s:套接字文件
p:命名管道
5.-size 按文件大小查找
常用单位K,M,G
#查找/data目录下大小等于3k的文件,-maxdepth 1 表示只进入一级目录。 #这里需提一下,find会把大于2k小于3k的文件当作等于3k。 [root@test ~]$find /data -maxdepth 1 -size 3k -ls 6422530 4 -rw-r--r-- 1 root root 2204 Sep 10 2015 /data/mysql_ins_5623.sh #查找/data目录下小于4k的文件。如果条件改为-size -3k,mysql_ins_5623.sh则无法匹配. #上例说了find把它当成等于3k看待所以不小于3k。 [root@test ~]$find /data -maxdepth 1 -size -4k -ls 6422531 0 -rwxrwxrw- 1 root root 0 Sep 10 2015 /data/e 6422530 4 -rw-r--r-- 1 root root 2204 Sep 10 2015 /data/mysql_ins_5623.sh #查找/data目录下大于3G的文件。 [root@test ~]$find /data -size +3G | xargs ls -alh -rwxr--r-- 1 root root 3.1G Nov 28 2015 /data/2008R2X64.iso -rwxr--r-- 1 root root 4.0G Sep 11 2015 /data/CentOS-6.3-x86_64-bin-DVD1.iso
6.根据时间戳查找
以“天”为单位:
-atime 按照文件的访问时间来查找, -n 查找系统中n天内访问的文件, +n 查找系统中n天以前访问的文件。n表示查找正好第n天访问的文件。
查找/tmp目录下访问时间为3天的文件 [root@test ~]$find /tmp/ -atime 3 -ls 9961484 4 -rw-r--r-- 1 root root 6 Jun 20 17:21 /tmp/test.conf
-ctime 按照文件状态改变时间来查找。 原理同atime
查找/data目录下3天内文件状态改变的文件,如文件移动过、更改过属主属组等,atime和mtime不会改变只会改变ctime [root@test53 ~]# find /data/ -ctime -3 /data/script/kvm_install /data/script/kvm_install/hostinfo /data/script/phy_install
-mtime 按照文件的修改时间来查找文件。原理同atime
查找/chenss目录下200天前修改过内容的文件并打包 [root@test tmp]$find /chenss/ -mtime +200 > test.list [root@test chenss]$tar -T test.list -zcvPf test.gar.gz /chenss/SSHLoginC.py /chenss/sshexecC.py
以“分钟”为单位原理同上
-amin
-cmin
-mmin
7.-perm 根据权限来查找文件
-perm mode 严格匹配mode,需和文件权限完全匹配
#查找/tmp目录下权限为777的文件 [root@test ~]$find /tmp/ -perm 777 -ls 9961483 0 srwxrwxrwx 1 mysql mysql 0 May 26 13:37 /tmp/mysql.sock
-perm -mode 文件的权限包含mode
[root@test ~]$find /chenss/ -perm -401 -ls 1835009 4 drwxr-xr-x 2 root root 4096 Jun 21 13:50 /chenss/ 1835014 4 -rw-r--r-x 1 root root 634 Dec 15 2015 /chenss/iptables.sh
-perm +mode 文件的权限部分匹配mode
[root@test ~]$find /chenss/ -perm +001 -ls 1835009 4 drwxr-xr-x 2 root root 4096 Jun 21 13:50 /chenss/ 1835014 4 -rw-r--r-x 1 root root 634 Dec 15 2015 /chenss/iptables.sh -perm为+771时你会发现network-analysis.sh也会被匹配,这是因为u权限7包含rw,g权限包含r,所以用+mode时权限千万不要用7否则会匹配所有文件。 [root@test ~]$find /chenss/ -perm +771 -ls 1835009 4 drwxr-xr-x 2 root root 4096 Jun 21 13:50 /chenss/ 1835012 4 -rw------- 1 root root 1483 Dec 10 2015 /chenss/realserver.sh 1837548 4 -rw-r--r-- 1 root root 1567 May 17 23:02 /chenss/swsnmp.sh 1835014 4 -rw-r--r-x 1 root root 634 Dec 15 2015 /chenss/iptables.sh 1838874 12 -rw-r--r-- 1 root root 9906 Jun 21 13:17 /chenss/network-analysis.sh
-perm /mode 等同于-perm +mode
[root@test ~]$find /chenss/ -perm /001 -ls 1835009 4 drwxr-xr-x 2 root root 4096 Jun 21 13:50 /chenss/ 1835014 4 -rw-r--r-x 1 root root 634 Dec 15 2015 /chenss/iptables.sh
9.-path与-prune 当我们使用find查找某目录下的文件却不想查找指定的子目录时就需要用到它们了。不过需要注意的是当find用了-depth时-prune会失效。-prune在匹配对应-path后的目录的同时不进入目录下查找。
用法:
find . -path "./sr*sc" -prune -o print #如果查找路径用的是相对路径;-path后面则只能跟相对路径,否则查找结果不会忽略-path后面跟的目录。 find /tmp -path "/tmp/sr*sc" -prune -o print #如果查找路径用的是绝对路径-path后面跟的也必须是绝对路径。
#查找/tmp目录下以.conf结属的文件并忽略hsperfdata_nginx和hsperfdata_root目录 #方法一: [root@test tmp]$find . -path "./hsperfdata*" -prune -o -name "*.conf" ./test.conf ./hsperfdata_nginx ./TEST.conf ./hsperfdata_root #命令尾部加-print参数,输出可忽略-path后面的目录。 [root@test tmp]$find . -path "./hsperfdata*" -prune -o -name "*.conf" -print ./test.conf ./TEST.conf #方法二:-path后面跟的路径千万不要补全,也就是最后一个“/”不要加,写成“./hsperfdata_nginx”, 而不是“./hsperfdata_nginx/”,否则结果不是我们期望的。小括号指示括号内的内容留给find去解释,需转义。 另要注意的是小括号前后需要加个空格否则会语法错误。 [root@test tmp]$find . \( -path "./hsperfdata_nginx" -o -path "./hsperfdata_root" \) -prune -o -name "*.conf" -print ./test.conf ./TEST.conf #方法三:需要注意的是“,”两边都各有一个空格。 [root@test tmp]$ find . -path "./hsperfdata_nginx" -prune , -path "./hsperfdata_root" -prune -o -name "*.conf" -print ./test.conf ./TEST.conf #方法四:不加-prune也可忽略-path后的目录,但实际上find是有搜索过"./hsperfdata_*"目录下的文件,只是因为-print 位于-o的右侧,"./hsperfdata_*“下匹配到的文件无法输出打印。不建议这种方式。 [root@test tmp]$find . -path "./hsperfdata_*" -o -name "*.conf" -print ./test.conf ./TEST.conf #方法五: [root@test tmp]$find . -name "hsperfdata_*" -prune -o -name "*.conf" -print ./test.conf ./TEST.conf [root@test tmp]$find . -type d -name "hsperfdata_*" -prune -o -name "*.conf" -print ./test.conf ./TEST.conf #错误用法:查找路径用的是相对路径,-path后跟的是绝对路径,所以查找结果未忽略hsperfdata开头的目录。 [root@test tmp]$find . -path "/tmp/hsperfdata*" -prune -o -name "*.conf" -print ./test.conf ./hsperfdata_nginx/abc.conf ./TEST.conf ./hsperfdata_root/abc.conf 说明: -path "./hsper*" -prune其实是-path "./hsper*" -a -prune的简写。-a和-o是短路求值(只要最终的结果已经可以确定 是真或假求值过程便告终止这称之为短路求值,short-circuit evaluation。)与 shell的&&和||类似。如果"./hsper*"文 件夹存在,也就是为真,则求-prune的值,-prune返回真,表示"与“表达式为真,则忽略”.hsper“文件夹。find将查找当前目录 下除"hsper*"子目录下的所有以“.conf”结尾的文件。
二、处理动作
-print 默认处理动作打印到屏幕
-ls 类似于ls -l,详细显示查找到的文件信息,组合查找时默认只显示查找到的右侧靠近ls的部分的信息,需对整个命令引用起来才可显示全部结果,本文前部分有很多示例都用了此处理动作。
-delete 删除查找到的文件
[root@test tmp]$find ./hsperfdata_nginx/ -name "*.conf" -delete
-exec COMMAND {} \; 对查找出来的每个文件执行指定命令动作,{}的作用是引用查找到的文件名本身
#查找当前目录下除"hsperdata_*"子目录下的以“.conf”结尾的文件。并copy到当前目录的test子目录下。 [root@test tmp]$find . -path "./hsperfdata_*" -prune -o -name "*.conf" -exec cp -r {} ./test \;
-ok COMMAND {} \; 意义同-exec,不同的是每一个命令动作需确认
备注:一次性查找符合条件的所有文件并一同传递给-exec或-ok后面指定的命令,但有些命令不能接受过长的参数此时,使用另一种方式 find | xargs COMMAND 查找文件,按次序一个个传递给管道后的命令。
参考文档
http://stackoverflow.com/questions/1489277/how-to-use-prune-option-of-find-in-sh
转载于:https://blog.51cto.com/wuyanc/1792358