find 命令工作方式:沿着文件层次结构向下遍历,匹配符合条件的文件,执行相应的操作。
$ find . -print
# 打印文件和目录列表
-
.
指定当前目录 -
-print
指明打印出匹配文件的文件名(路径)。此时将使用\n
作为输出文件名之间的定界符。此项可以不写,也能打印。 -
-print0
指明使用\0
作为输出文件名之间的定界符。
1. 根据文件名或正则表达式进行搜索
-
-name
指定文件名所必须匹配的字符串$ find . -name "*.txt" -print # 查找当前目录下所有以 .txt 结尾的文件名
-iname
同上,但会忽略字母大小写-
-o
OR 条件操作,匹配多个条件中的一个$ find . \( -name "*.txt" -o -name "*.pdf" \) -print # 查找当前目录下所有的 .txt 和 .pdf 文件
-
-path
匹配文件路径$ find . -path "*/source/*" -print # 匹配当前目录下所有 source 子目录
-
-regex
正则表达式$ find . -regex ".*\(\.py\|\.sh\)$" # 查找当前目录下所有 .py 和 .sh 文件
-iregex
同上,但忽略大小写
2. 否定参数
$ find . ! -name "*.txt" -print
# 查找当前目录下所有不以 .txt 结尾的文件
3. 基于目录深度的搜索
-
-maxdepth
指定查找目录的最大深度。
$ find . -maxdepth 1 -name "f*" -print
# 查找当前目录下的所有文件名以 f 开始的文件。不查找子目录。
-
-mindepth
指定开始遍历的最小深度。
$ find . -mindepth 3 -name "f*" -print
./dir1/dir2/file1
./dir3/dir4/f2
# 即使当前目录或 dir1 和 dir3 中包含文件,它们也不会被打印出来。
-maxdepth
和-mindepthe
应该作为find
的第三个参数出现。如果作为第四个或之后的参数,就可能会影响到find
的效率,因为它不得不进行一些不必要的检查。
4. 根据文件类型搜索
-type
可以指明特定的文件匹配类型。
如只列出所有的目录:
find . -type d -print
文件类型 | 类型参数 |
---|---|
普通文件 | f |
符号链接 | l |
目录 | d |
字符设备 | c |
块设备 | b |
套接字 | s |
FIFO | p |
5. 根据文件时间进行搜索
Unix/Linux 文件系统中的每一个文件都有三种时间戳:
-
访问时间(
-atime
):用户最近一次访问文件的时间。 -
修改时间(
-mtime
):文件内容最后一次被修改的时间。 -
变化时间(
-ctime
):文件元数据(例如权限或所有权)最后一次改变的时间。
在 Unix 中并没有所谓“创建时间”的概念。
以天数为单位进行搜索
-atime
、-mtime
、-ctime
用整数值指定,单位是天。
- 打印处最近 7 天内被访问过的所有文件:
find . -type f -atime -7 -print
- 打印出恰好在 7 天前被访问过的所有文件:
find . -type f -atime 7 -print
- 打印出访问时间超过 7 天的所有文件:
find . -type f -atime +7 -print
以分钟为单位进行搜索
-amin
、-mmin
、-cmin
用整数值指定,单位是分钟。
打印出访问时间超过 7 分钟的所有文件:
find . -type f -amin +7 -print
以参考文件进行搜索
-newer
指定一个用于比较时间戳的参考文件,然后找出比参考文件更新的(更近的修改时间)所有文件。
找出比 file.txt 修改时间更近的所有文件:
find . -type f -newer file.txt -print
6. 基于文件大小的搜索
$ find . -type f -size +2k
# 大于2KB的文件
$ find . -type f -size -2k
# 小于2KB的文件
$ find . -type f -size 2k
# 等于2KB的文件
可用文件大小单元:
-
c
字节 -
w
字(2 字节) -
b
块(512 字节) -
k
1024 字节 -
M
1024k 字节 -
G
1024M 字节
7. 删除匹配的文件
$ find . -type f -name "*.txt" -delete
# 删除当前目录下所有 .txt 文件
8. 基于文件权限和所有权的匹配
$ find . -type f -perm 644 -print
# 打印出权限为 644 的文件
$ find . -type f -user sky -print
# 打印出用户 sky 拥有的所有文件
9. 利用 find 执行命令或动作
$ find . -type f -user root -exec chown sky {} \;
# 将当前目录下所有 root 用户文件的文件所有权改成 sky 用户
# 对于每一个匹配的文件,`{}`会被替换成相应的文件名
# 如果希望使用文件列表作为命令参数,可以在 exec 中使用 `+` 来代替 `;`
$ find . -type f -name "*.c" -exec cat {} \;> all_c_files.txt
# 将当前目录下的所有C程序文件拼接起来写入单个文件 all_c_files.txt
# 因为 find 命令的全部输出就只有一个数据流(stdin),所以只需要使用 `>` 操作符
-exec
结合多个命令我们无法在
-exec
参数中直接使用多个命令。但是可以把多个命令写到一个 shell 脚本中,然后在-exec
中使用这个脚本:-exec ./commands.sh {} \;
10. 让 find 跳过特定的目录
$ find . \( -name ".git" -prune \) -o \( -type f -print \)
# 打印出不包括在 .git 目录中的所有文件的名称(路径)