linux文件查找命令之find详解

find命令是linux下最经常使用的一个命令,它能够根据文件名、文件属性、类型、大小、时间戳等来实时查找你须要的文件,并可针对搜索结果进行处理。
mysql


语法:find [查找路径] [查找条件] [处理动做]linux

查找路径:默认为当前目录nginx

查找条件:默认为指定路径 下的全部文件sql

处理动做:默认显示至屏幕shell




1、查找条件
centos

1.按文件名称查找bash

  • -name “文件名称“    支持使用globbing字符ssh

[root@test ~]$find /tmp -name 'test*'
/tmp/test.conf
  • -iname  按文件名称查找,忽略大小写ide

[root@test ~]$find /tmp -iname 'test*'
/tmp/test.conf
/tmp/TEST.conf


2.按文件属性查找ui

  • -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”结尾的文件。


2、处理动做

  • -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