find是UNIX/Linux命令行工具箱中最棒的工具之一。这个命令对编写shell脚本很有帮助。

一、根据文件名或正则表达式匹配搜索

-name "文件名称":根据文件名查找

[root@TP-CW-WS-DL-02 ~]# find /etc/ -name "passwd"
/etc/pam.d/passwd
/etc/passwd

支持通配符查找:查找/etc目录下所有以.d结尾的文件

[root@TP-CW-WS-DL-02 etc]# find /etc/ -name "*.d"
/etc/chkconfig.d
/etc/rwtab.d
/etc/bash_completion.d
/etc/cron.d
/etc/init.d
/etc/modprobe.d
/etc/rc0.d
/etc/logrotate.d
/etc/NetworkManager/dispatcher.d
/etc/dracut.conf.d
.......................................................

-iname:根据文件名精确查找,只不过在匹配名字的时候忽略大小写。

[root@TP-CW-WS-DL-02 tmp]# ls
abc.txt  alinux.txt  ALINux.txt  yum.log
[root@TP-CW-WS-DL-02 tmp]# find . -iname "alinux*"
./alinux.txt
./ALINux.txt

-user:根据属组来查找:

-group GROUPNAME:根据属组查找:

查找/home目录下属组为centos的文件(-ls:显示查找到的文件的详细信息:


[root@TP-CW-WS-DL-02 jiabin]# find /home/ -user centos -ls
1046529    4 drwx------   7 centos   centos       4096 Oct 19 12:52 /home/centos
1046533    4 -rw-r--r--   1 centos   centos        176 May 31  2011 /home/centos/.bash_profile
1046531    4 -rw-r--r--   1 centos   centos        124 May 31  2011 /home/centos/.bashrc
1046530    4 drwxr-xr-x   2 centos   centos       4096 Nov 12  2010 /home/centos/.gnome2
1046532    4 -rw-r--r--   1 centos   centos         18 May 31  2011 /home/centos/.bash_logoutg-group:g


根据用户的uid和gid查找

-uid UID;

-gid GID;

[root@TP-CW-WS-DL-02 ~]# find /home/ -uid 502
/home/centos
/home/centos/.bash_profile
/home/centos/.bashrc
/home/centos/.gnome2
/home/centos/.bash_logout

-nouser:查找没属主的文件;

-nogroup:查找没有属组的文件;

[root@localhost ~]# find /home/ -nouser -ls
15401186    4 drwx------   3 528      pr           4096 11月 11  2012 /home/tina_liu
15401187    4 -rw-r--r--   1 528      pr            124 11月 11  2012 /home/tina_liu/.bashrc
15401188    4 -rw-r--r--   1 528      pr            515 11月 11  2012 /home/tina_liu/.emacs
15401189    4 -rw-r--r--   1 528      pr            176 11月 11  2012 /home/tina_liu/.bash_profile
15401190    4 -rw-r--r--   1 528      pr             33 11月 11  2012 /home/tina_liu/.bash_logout
15401191    4 drwxr-xr-x   4 528      pr           4096 11月 11  2012 /home/tina_liu/.mozilla
15401192    4 drwxr-xr-x   2 528      pr           4096 11月 11  2012 /home/tina_liu/.mozilla/extensions
15401193    4 drwxr-xr-x   2 528      pr           4096 11月 11  2012 /home/tina_liu/.mozilla/plugins

组合条件查找:

-a:与

-o:或

-not,!:非

[root@TP-CW-WS-DL-02 tmp]# ls
abc.txt  alinux.txt  ALINux.txt  new.txt  some.jpe  test.pdf  yum.log
[root@TP-CW-WS-DL-02 tmp]# find . \( -name "*.txt" -o -name "*.pdf" \) -print
./alinux.txt
./new.txt
./abc.txt
./test.pdf
./ALINux.txt

上面的代码会打印出所有的.txt和.pdf文件,是因为这个find命令能够匹配所有这两类文件。\(以及\)用于将-name "*.txt" -o -name" *.pdf"视为一个整体。

二、根据文件类型搜索

-type

文件类型类型参数
普通文件f
符号链接l
目录d
字符设备c
块设备b
套接字s
Fifo(命名管道)p

-size

size前不加任何(+,-)表示精确匹配,

如-size 2M(大于1MB小于2MB的文件)

-size +2M(大于2MB的文件)

--size -2M(小于2MB的文件)

注意:要匹配k字节单位的,必须使用小写的k

以时间为天计算:

-atime:[+|-]文件的访问时间

-mtime:[+|-]文件的修改时间

-ctime:[+|-]文件的改变时间

以时间为分计算:

-amin[+|-]

-mmin[+|-]

-cmin[+|-]


-perm[+|-]MODE :权限匹配

没有[+|-]精确匹配

+MODE:任何一类用户任何一位权限匹配即可

如:+111 任何一类用户有执行权限即可

-MODE:每类用户每位权限都需要匹配

如:-111 每类用户都需要有执行权限即可

[root@TP-CW-WS-DL-02 centos]# chmod 644 *
[root@TP-CW-WS-DL-02 centos]# ls -lh
total 16K
drw-r--r--. 2 root root 4.0K Oct 19 12:52 bin
drw-r--r--. 2 root root 4.0K Oct 19 12:52 lib
drw-r--r--. 2 root root 4.0K Oct 19 12:52 sbin
drw-r--r--. 5 root root 4.0K Oct 19 12:52 usr
[root@TP-CW-WS-DL-02 centos]# find ./ -perm -666 -ls
#搜索不到,因为-666必须每个文件的三类权限都需要符合读写。
[root@TP-CW-WS-DL-02 centos]# chmod 777 lib/
[root@TP-CW-WS-DL-02 centos]# find ./ -perm -666 -ls
1046543    4 drwxrwxrwx   2 root     root         4096 Oct 19 12:52 ./lib
这样就可以搜索出来了。

处理动作

-print:显示

-ls:显示查到的文件的详细信息:

-exec COMMAND \;

在这个命令中,{ }是一个特殊的字符串,与-exec选项结合使用。对于每一个匹配的文件,{ }会被替换成相应的文件名。例如,find命令找到两个文件test1.txt和test2.txt,其所有者均为slynux,那么find将会执行:

chown slynux {}

它会被解析为chown slynux test1.txt 和chown slynux test2.txt

将给定目录中的所有C程序文件拼接起来写入单个文件all_c_files.txt可以用find找到所有的C文件,然后结合-exec使用cat命令

[root@TP-CW-WS-DL-02 /]# find . -type f -name "*.c" -exec cat {} \;>all_c_files.txt
[root@TP-CW-WS-DL-02 /]# wc -l all_c_files.txt
1069 all_c_files.txt

-exec之后可以接任何命令。{}表示一个匹配。对于任何一个匹配的文件名,{}会被该文件名所替换。

用下列命令将10天前的.txt文件复制到/root目录中:

find . -type f -mtime +10 -name "*.txt" -exec cp {} /root \;

三、补充知识

1、让find跳过特定的目录

在搜索目录并执行某些操作的时候,有是为了提高性能,需要跳过一些子目录。其操作方法如下:

find /devel/source_path \(-name ".git" -prune \) -o \(-type f -print \)

这里, \( -name ".git" -prune \)的作用是用于进行排除,它指明了,git目录应该被排除掉,而\( -type f -print \)指明了需要执行的动作。这些动作需哟啊被放置在第二个语句块中(打印出所有的文件的名称和路径)

2、结合find使用xargs

xargs和find算是一对死党。两者结合使用可以让任务变得更轻松。不过有中错误的组合方式。例如:

find . -type f -name "*.txt" -print |xargs rm -f

这样做很危险。有是可能会删除不必要删除的文件。很多文件名中都可能会包含空格符,xargs很可能会误认为他们是定界符(例如,hell text.txt 会被xargs误认为hell和text.txt)

只要我们把find的输出作为xargs的输入,就必须将-print0与find结合使用,以字符null来分隔输出。

用find匹配并列出所有的.txt文件,然后用xargs将这些文件删除:

find . -type f -name "*.txt" -print0 | xargs -0 rm -f

四、综合练习

1、查找/var目录下属主为root并且属组为mail的所有文件;

find /var -user root -group mail


2、查找/usr目录下不属于root,bin,或student的文件;

find /usr -not \( -user root -o -user bin -o -user student \)

find /usr -not -user root -a -not -user bin -a -not -user student


3、查找/etc目录下最近一周内内容修改过且不属于root及student用户的文件;

find /etc -mtime -7 -a -not -user root -a -not -user student

find /etc -mtime -7 -a -not \( -user root -o -user student \)


4、查找当前系统上没有属主或属组且最近1天内曾被访问过的文件,并将其属主属组均修改为root;

find / \( -nouser -o -nogroup \) -a -atime -1 -exec chown root:root {} \;


5、查找/etc目录下大于1M的文件,并将其文件名写入/tmp/etc.largefiles文件中;

find /etc -size +1M -exec echo {} >> /tmp/etc.largefiles \;

find /etc -size +1M >> /tmp/etc.largefiles


6、查找/etc目录下所有用户都没有写权限的文件,显示出其详细信息;

find /etc -not -perm +222

find / \( -nouser -o -nogroup \) -a -atime -1 | xargs -i chown root:root {}

类型不是目录,而且没有属主的文件;

find / -not -type d -a -nouser -exec rm -f {} \;

find / -not -type d -a -nouser | xargs -i rm -f {}

find / -size +10M -a -atime +10 -exec mv {} {}.old \;