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 \;