UNIX中的find命令是一个用于遍历文件层次结构的命令行实用程序。它可以用来查找文件和目录,并对它们执行后续操作。它支持搜索文件,文件夹,名称,创建日期,修改日期,所有者和权限。通过使用’ -exec ‘,其他UNIX命令可以在找到的文件或文件夹上执行。
常用方式:
- 根据文件名或正则表达式进行搜索
- 否定参数
- 基于目录深度的搜索
- 根据文件类型搜索
- 根据文件的时间戳进行搜索
- 基于文件大小的搜索
- 基于文件权限和所有权的匹配
- 利用find执行相应操作
- 让find跳过特定的目录
1:根据文件名或正则表达式进行搜索
-name选项指定了待查找文件名的模式。这个模式可以是通配符,也可以是正则表达式。
find命令支持逻辑操作符。-a和-and选项可以执行逻辑与(AND)操作,-o和-or选项可以执行逻辑或(OR)操作。
#找出.txt结尾的文件
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find /tmp/ -name ‘*.txt’
/tmp/testscripterror.txt
/tmp/testscript.txt
#找出.txt或者.sock结尾的文件
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find /tmp/ \( -name ‘.txt’ -o -name ‘.sock’ \)
/tmp/mysql.sock
/tmp/testscripterror.txt
/tmp/testscript.txt
/tmp/php-cgi-73.sock
#-regex选项
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find /tmp/ -regex ‘.*.txt’
/tmp/testscripterror.txt
/tmp/testscript.txt
2:否定参数
#找出不是.txt结尾的文件
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find /tmp/ ! -name “*.txt”
3:基于目录深度的搜索
find命令在查找时会遍历完所有的子目录。-maxdepth和-mindepth选项可以限制find命令遍历的目录深度。这可以避免find命令没完没了地查找。
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find . -maxdepth 2 -name “*.php”
./wordpress/wp-mail.php
./wordpress/wp-activate.php
./wordpress/wp-signup.php
./wordpress/wp-settings.php
./wordpress/wp-blog-header.php
./wordpress/wp-config.php
./wordpress/xmlrpc.php
./wordpress/wp-trackback.php
./wordpress/wp-load.php
./wordpress/wp-comments-post.php
./wordpress/wp-links-opml.php
./wordpress/wp-cron.php
./wordpress/index.php
./wordpress/wp-login.php
4:根据文件类型搜索
类Unix系统将一切都视为文件。文件具有不同的类型,例如普通文件、目录、字符设备、块设备、符号链接、硬链接、套接字以及FIFO等。
find命令可以使用-type选项对文件搜索进行过滤。借助这个选项,我们可以告诉find命令只匹配指定类型的文件。
#找出目录
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find blog/ -maxdepth 2 -type d
blog/
blog/project
blog/project/environments
blog/project/common
blog/project/frontend
blog/project/vendor
blog/project/console
blog/project/backend
blog/project/vagrant
blog/.git
blog/.git/hooks
blog/.git/objects
blog/.git/refs
blog/.git/branches
blog/.git/logs
blog/.git/info
#只列出普通文件:
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find blog/ -maxdepth 2 -type f
blog/project/requirements.php
blog/project/init.bat
blog/project/Vagrantfile
blog/project/LICENSE.md
blog/project/composer.lock
blog/project/.bowerrc
blog/project/yii
blog/project/yii.bat
blog/project/.gitignore
blog/project/init
blog/project/codeception.yml
blog/project/composer.json
blog/.git/ORIG_HEAD
blog/.git/FETCH_HEAD
blog/.git/config
blog/.git/index
blog/.git/HEAD
blog/.git/description
blog/.git/packed-refs
5:根据文件的时间戳进行搜索
Unix/Linux文件系统中的每一个文件都有3种时间戳,如下所示。
- 访问时间(-atime):用户最近一次访问文件的时间。
- 修改时间(-mtime):文件内容最后一次被修改的时间
- 变化时间(-ctime):文件元数据(例如权限或所有权)最后一次改变的时间。
-atime、-mtime以及-ctime都是以“天”为单位来计时的。find命令还支持以“分钟”为计时单位的选项。这些选项包括:
- -amin(访问时间);
- -mmin(修改时间);
- -cmin(变化时间)。
-newer选项可以指定一个用于比较修改时间的参考文件,然后找出比参考文件更新的(更近的修改时间)所有文件。 -atime、-mtime和-ctime可作为find的时间选项。它们可以用整数值来指定天数。 这些数字前面可以加上-或+。-表示小于,+表示大于。
#查出打印出在最近7天内被访问过的所有文件。
[root@iZ2ze9v82ax0ox0j12ahfhZ wwwroot]# find blog/ -type f -atime -7
#打印出恰好在7天前被访问过的所有文件
[root@iZ2ze9v82ax0ox0j12ahfhZ wwwroot]# find blog/ -type f -atime 7
#打印出访问时间超过7天的所有文件。
[root@iZ2ze9v82ax0ox0j12ahfhZ wwwroot]# find blog/ -type f -atime +7
6:基于文件大小的搜索
文件单位:
- b:块(512字节)。
- c:字节。
- w:字(2字节)。
- k:千字节(1024字节)。
- M:兆字节(1024K字节)。
- G:吉字节(1024M字节)。
#超出大于2M的文件
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find blog/ -type f -size +2M
blog/project/vendor/bower/punycode/tests/data.js
7:基于文件权限和所有权的匹配
-perm选项指明find应该只匹配具有特定权限值的文件 #找出权限644的文件 [zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find blog/ -type f -perm 644
用选项 -user USER就能够找出由某个特定用户所拥有的文件。参数USER可以是用户名或UID。
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find blog/ -type f -user www
8:利用find执行相应操作
find命令能够对其所查找到的文件执行相应的操作。无论是删除文件或是执行任意的Linux命令都没有问题。
find命令的-delete选项可以删除所匹配到的文件。
#下面的命令能够从当前目录中删除.swp文件:
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ tmp]# find . -type f -name “*.swap” -delete
利用-exec选项,find命令可以结合其他命令使用
find命令使用一对花括号{}代表文件名。
#将.txt的的权限改为755
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ tmp]# find /tmp/ -name “.txt”
/tmp/testscripterror.txt
/tmp/testscript.txt
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ tmp]# find /tmp/ -name “.txt” -exec chmod 755 {} \;
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ tmp]# ls -l /tmp/testscripterror.txt
-rwxr-xr-x 1 root root 468 Nov 7 20:24 /tmp/testscripterror.txt
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ tmp]# ls -l /tmp/testscript.txt
-rwxr-xr-x 1 root root 981 Nov 7 20:24 /tmp/testscript.txt
注意该命令结尾的\;。必须对分号进行转义,否则shell会将其视为find命令的结束,而非chmod命令的结束
9:让find跳过特定的目录
在find的执行过程中,跳过某些子目录能够提升性能。
在搜索时排除某些文件或目录的技巧叫作修剪。下面的例子演示了如何使用-prune选项排除某些符合条件的文件:
[zhangsan@iZ2ze9v82ax0ox0j12ahfhZ ~]# find ./ -maxdepth 2 -name ‘.git’ -prune -o -type f -print
./project/requirements.php
./project/init.bat
./project/Vagrantfile
./project/LICENSE.md
./project/composer.lock
./project/.bowerrc
./project/yii
./project/yii.bat
./project/.gitignore
./project/init
./project/codeception.yml
./project/composer.json
-name “.git” -prune是命令中负责进行修剪的部分,它指明了.git目录应该被排除在外。-type f -print描述了要执行的操作。
参考资料:
- 《Linux Shell脚本攻略(第3版)》