一、介绍

   由于find具有强大的功能,即使系统中含有网络文件系统(NFS),find命令在该文件系统中同样有效,只要你具有相应的权限。

   find命令是一个非常消耗IO的命名,很多人都倾向于把它放在后台执行, 或用locate代替

   find命令的一般形式为:

   find pathname options

  参数说明:

   pathname 是要搜索的路径

   -options 是可以增加的选项

二、选项说明

  -name 

  按照文件名查找文件,支持*号和[]号。

  -perm

  按照文件权限来查找文件,支持完全指定和-号、+号部分符合。

  -prune

  使用该选项可以使find命令不在当前指定的目录中查找,如果同时使用-depth选项,那么-prune将被find命令忽略。

  -user

  按照文件属主来查找文件。

  -group

  按照文件所属的组来查找文件。

  -mtime -n +n

  按照文件的更改时间来查找文件

  -amin -n +n

  按照文件的访问时间来查找文件

  -cmin -n +n

  按照文件状态的更改时间来查找文件  - n表示文件更改时间距现在n天以内,+ n表示文件更改时间距现在n天以前。 

  -nogroup

  查找无有效所属组的文件,即该文件所属的组在/etc/groups中不存在。

  -nouser

  查找无有效属主的文件,即该文件的属主在/etc/passwd中不存在。

  -newer file1 ! -newer file2

  查找更改时间比文件file1新但比文件file2旧的文件。

  -type 

  查找某一类型文件,:b-块设备文件;d-目录;c-字符设备文件;p-管道文件;l-符号链接文件;f-普通文件。

  -size n[c] 查找文件长度为n块的文件,带有c时表示文件长度以字节计。

  -depth:在查找文件时,首先查找当前目录中的文件,然后再在其子目录中查找。

  -fstype:查找某一类型文件系统中的文件(:nfs,ext3,vfat),这些文件系统类型通常可以在配置文件/etc/fstab中找到,该配置文件中包含了本系统中有关文件系统的信息。

  -mount:在查找文件时不跨越文件系统mount点。

  -follow:如果find命令遇到符号链接文件,就跟踪至链接所指向的文件。

  -regex pattern:对搜索结果的整个路径按正规表达式进行过滤,必须对全路径考虑,例如结果是./test,那正规表达式应该用"./t.*",而不能用"t.*"

  -cpio:对匹配的文件使用cpio命令。

另外,在使用多个参数的时候,find命令还支持使用逻辑运算符:

  -a 类似&&,也就是与,当第一个参数运行为真,才运行后面的参数

  -o 类似||,也就是或,当第一个运行为假,则运行后面的参数

  !,也就是非、否

三、举例说明

1.使用name选项

  $ find ~ -name "*.txt" -print

查找用户主目录下所有结尾是.txt的文件和目录等

2.使用perm选项

  $ find . -type f -perm 644 -print

  显示当前目录下的所有权限是644的普通文件

  $ find . -perm -7 -print

  显示当前目录下权限为777的文件和目录等,-7表示用户、主、其他权限中都必须是7

  说明:

  -号表示权限要全包含,例如-4,则644646446都可以找到,但640就不会显示;
  +
号表示权限可以部分包含,例如+4,则644644甚至640404都会显示;

3.忽略某个目录

  $ find /apps -path "/apps/bin" -prune -o -print

  显示/apps目录中,除/apps/bin目录的所有文件和目录等;也就是当-path "/apps/bin"找到,则-prune,否则就-print

  find /test \( -path /test/dir1 -o -path /test/file1 \) -prune -o -name "temp" -print

  /test目录下除了/test/dir1/test/file1目录外的其他目录中的temp文件和目录等

4.使用usernouser选项

  如果希望按照文件属主查找文件,可以给出相应的用户名。

  $ find ~ -user dave print

  $home目录中查找文件属主为dave的文件,

  为了查找属主帐户已经被删除的文件,可以使用-nouser选项。这样就能够找到那些属主

  /etc/passwd文件中没有有效帐户的文件。在使用-nouser选项时,不必给出用户名;

  $ find /home -nouser print

  希望在/home目录下查找所有的这类文件

5.使用groupnogroup选项

  使用方法和上面一样,这里就不做介绍。

6.按照更改或访问时间查找文件

  如果希望按照更改时间来查找文件,可以使用mtime选项。按访问时间来查找文件,可以使用atime选项;用“减号-”来限定更改时间在距今 n日以内的文件,而用“加号 +”来限定更改时间在距今n日以前的文件。

  $ find /var/logs -type f -mtime +7

  显示/var/logs目录下,更改时间在7日前的文件

  $ find /var/logs -amin +2 -amin -6

  显示/var/logs目录下,2~6分钟前被访问过的文件。

  $ find /var/logs -type f -daystart -mtime -1

  查找/var/logs目录下,1天内被修改过的文件。而-daystart是假设原点为实际时间,而不是从当前推算的24小时方式计算。

7.查找比某个文件新或旧的文件

  如果希望查找更改时间比某个文件新但比另一个文件旧的所有文件,可以使用-newer选项。

  $ find . -newer httpd1.conf ! -newer temp

  找当前目录下比httpd1.conf新,但比temp旧的文件和目录等

8.使用type选项

  find命令通过使用-type选项对查找的内容进行选择

  $ find . ! -type d -print

  找当前目录下除目录外的其他文件等(包括设备、链接文件)

9.使用size选项

  可以按照文件长度来查找文件,这里所指的文件长度既可以用块来计量,也可以用字节来计量。以字节计量文件长度的表达形式为“数字+c”;以块计量文件长度只用数字表示即可。

  $ find . -size +1000000c -print

  显示当前目录文件大小超过1M字节的文件

  $ find /home/linuxing -size 100c -print

  /home/linuxing目录下刚好100字节的文件

  $ find . -size +10 -print

  找当前目录下超过10个块的文件(1个块默认是512字节)

10.使用depth选项

  在使用find命令时,可能希望先匹配所有的文件,再在子目录中查找。可以通过使用-depth选项来实现。

  $ find / -name "test" -depth -print

  按先找完起始目录,再进入子目录查找的方式找test文件

11.使用mount选项

  在当前的文件系统中查找文件(不进入其他文件系统),可以使用find命令的mount选项。

  $ find . -name "test" -mount -print

  找位于本文件系统上的当前目录中的test文件或目录等(不跨文件系统)

12.使用cpio选项

  cpio命令可以用来向磁带设备备份文件或从中恢复文件。可以使用find命令在整个文件系统中(更多的情况下是在部分文件系统中)查找文件,然后用cpio命令将其备份到磁带上。

  $ cd /

  $ find etc home depth | cpio ivcdC65536 o /dev/rmt0

  备份/etc/home目录中的文件,不过要必须要在文件系统的根目录下。

  在上面的例子中,应当注意到路径中缺少 /。这叫作相对路径。之所以使用相对路径,是因为在从磁带中恢复这些文件的时候,可以选择恢复文件的路径。例如,可以将这些文件先恢复到另外一个目录中,对它们进行某些操作后,再恢复到原始目录中。如果在备份时使用了绝对路径,例如/etc,那么在恢复时,就只能恢复到/etc目录中去,别无其他选择。

13.使用regex选项

  可以通过使用regex选项对find命令查找到得结果进行过滤。

  $ ls -l

  total 2

  -rw-r--r--  1 root  wheel   0 Dec 28 11:39 001

  -rw-r--r--  1 root  wheel   0 Dec 28 11:39 002

  -rw-r--r--  1 root  wheel  36 Dec 28 18:05 test

  $ find . -name "00*" -regex "00.*"

  $ find . -name "00*" -regex "./00.*"

  ./001

  ./002

  $ find . -name "00*" -regex ".*0."

  ./001

  ./002

  -regex 后面跟的是正规表达式,并且是对包括全路径的结果做过滤

四、配合参数-exec-okxargs

  1.-exec-ok

  find命令可以使用-exec-ok参数直接对结果执行操作,-exec-ok后面跟执行的命令,然后是一对儿{},一个空格和一个\,最后是一个分号。

  exec-ok的区别是-exec是不会咨询用户是否确认的,但-ok会要用户对操作进行每一步的确认。

  # find . -name "00*" -exec ls -l {} \;

  -rw-r--r--  1 root  wheel  0 Dec 28 11:39 ./001

  -rw-r--r--  1 root  wheel  0 Dec 28 11:39 ./002

   对比上面命令的结果

  # find . -name "00*" -ok rm {} \;

  "rm ./001"? n

  "rm ./002"? n

  # find /etc -name "passwd*" -exec grep "linuxing" {} \;

  linuxing:*:1010:1010:linuxing:/home/linuxing:/bin/bash

   对比-exec-ok的结果

  2.-xargs

  另外,由于部分系统能否接受的参数是有限制的,但-exec-ok是把所有的结果作为整套参数传递,这会引起问题。所以也可以使用xargs配合达到同样的目的。在使用xargs命令时,究竟是一次获取所有的参数,还是分批取得参数,以及每一次获取参数的数目都会根据该命令的选项及系统内核中相应的可调参数来确定。

  $ find . -type f -name "00*" |xargs file

  ./001: ASCII text

  ./002: empty

  查找当前目录中开头是00的文件,并用file命令看看文件属性

  $ find . -perm 666 -print | xargs chmod o-w

  再找到本地目录中有666权限的文件或目录等后,把otherw权限去掉

  $ find /etc -name "passwd*" |xargs grep "linuxing"

  /etc/passwd:linuxing:*:1010:1010:linuxing:/home/linuxing:/bin/bash

  对比xargs-exec-ok的使用方式和结果