101117

506 分钟

#Bash 的 find 命令

find [OPTION]... [DIR...] [EXPRESSION]

功能

在目录层次结构中搜索文件。

类型

可执行文件(/usr/bin/find),属于 findutils

参数

  • OPTIONS 选项:
    • -P - 检查或打印文件信息时,不跟踪符号链接;默认
    • -L - 检查或打印文件信息时,跟踪符号链接
    • -H - 检查或打印文件信息时,除处理命令行参数外,不要跟踪符号链接
    • -D debugopts - 打印诊断信息
      • exec - 显示与 exec、execdir、ok 和 okdir 相关的诊断信息
      • opt - 打印与表达式树优化相关的诊断信息
      • rates - 打印一份摘要,指出每个谓词成功或失败的次数
      • search - 详细浏览目录树
      • stat - 使用 statlstat 系统调用检查文件时会打印消息;find 程序会尽量减少此类调用
      • tree - 显示表达式树的原始形式和优化形式
      • all - 启用所有调试选项
      • help - 查看调试选项的帮助
    • -O level - 启用查询优化;范围为 0(低) 至 3(高),默认为 1
  • DIR - 要搜索的目录
  • EXPRESSION - 匹配表达式
    • Tests - 匹配测试
      • -amin n - 文件在 n 分钟内 / n 分钟前 / 恰好 n 分钟前 被访问。
      • -anewer reference - 当前文件的最后访问时间比参考文件的最后数据修改时间更新。如果 reference 是符号链接,并且启用了 -H-L 选项,则始终使用其指向文件的最后数据修改时间。
      • -atime n - 文件在 n×24 小时内 / 之前 / 恰好 被访问。计算时会忽略小数部分,例如 -atime +1 表示至少 2 天前访问过
      • -cmin n - 文件的**状态(inode)**在 n 分钟内 / 之前 / 恰好 n 分钟前发生改变。
      • -cnewer reference - 当前文件的状态改变时间比参考文件的数据修改时间更新。符号链接规则同 -anewer
      • -ctime n - 文件状态在 n×24 小时内 / 之前 / 恰好 被修改。取整规则同 -atime
      • -empty - 文件为空(可以是普通文件或目录)。
      • -executable - 当前用户可执行的文件可搜索的目录(考虑 ACL 等权限)。
      • -false - 永远为假。
      • -fstype type - 文件所在文件系统类型为 type(如:nfs, tmp 等)。
      • -gid n - 文件的组 ID 小于 / 大于 / 等于 n。
      • -group gname - 文件属于组 gname(支持数字 GID)。
      • -ilname pattern - 类似 -lname,但忽略大小写
      • -iname pattern - 类似 -name,但忽略大小写
      • -inum n - 文件的 inode 编号小于 / 大于 / 等于 n。
      • -ipath pattern - 类似 -path,但忽略大小写。
      • -iregex pattern - 类似 -regex,但忽略大小写。
      • -iwholename pattern - 同 -ipath(兼容性较差)。
      • -links n - 文件的硬链接数小于 / 大于 / 等于 n。
      • -lname pattern - 文件是符号链接,且其内容匹配 shell 模式。
      • -mmin n - 文件数据在 n 分钟内 / 之前 / 恰好被修改。
      • -mtime n - 文件数据在 n×24 小时内 / 之前 / 恰好被修改。取整规则同 -atime
      • -name pattern - 文件名(不含路径)匹配 shell 模式。不包含 /,因此 -name a/b 永远匹配不到。
      • -newer reference - 当前文件的修改时间比参考文件更新。
      • -newerXY reference - 比较文件的时间戳:
      • a:访问时间
      • B:创建时间
      • c:状态改变时间
      • m:修改时间
      • t:直接使用时间字符串
      • -nogroup - 文件的 GID 没有对应的组。
      • -nouser - 文件的 UID 没有对应用户。
      • -path pattern - 完整路径匹配 shell 模式(包含 /)。
      • -perm mode - 权限完全匹配 mode(八进制或符号)。
      • -perm -mode - 文件包含所有指定权限位。
      • -perm /mode - 文件包含任意一个指定权限位。
      • -perm +mode - 已废弃(用 -perm /mode 替代)。
      • -readable - 当前用户可读(考虑 ACL)。
      • -regex pattern - 文件路径匹配正则表达式(默认 Emacs 风格)。
      • -samefile name - 与指定文件具有相同 inode。
      • -size n[cwbkMG] - 文件大小:
      • b:512 字节块(默认)
      • c:字节
      • w:2 字节
      • k:KiB
      • M:MiB
      • G:GiB
      • + 表示大于,- 表示小于。
      • -true - 永远为真。
      • -type c - 文件类型:
      • f:普通文件
      • d:目录
      • l:符号链接
      • b:块设备
      • c:字符设备
      • p:管道
      • s:socket
      • -uid n - 文件的 UID 小于 / 大于 / 等于 n。
      • -used n - 文件在状态改变后 n 天内 / 之后 / 恰好被访问。
      • -user uname - 文件属于用户 uname(支持 UID)。
      • -wholename pattern - 同 -path(兼容性较差)。
      • -writable - 当前用户可写(考虑 ACL)。
      • -xtype c - 类似 -type,但对符号链接检查其指向目标类型
      • -context pattern - (仅限 SELinux)安全上下文匹配模式。
    • Actions - 副作用
      • -delete - 删除匹配到的文件
      • -exec command ; - 对每个匹配文件执行一次命令;command 中的 {} 会被替换为当前文件路径
      • -exec command {} + - 对所有匹配文件一次性执行命令;{} 会被替换为所有文件路径
      • -execdir command ; - 类似 -exec command ;,但以 文件所在目录 作为执行命令的工作目录
      • -execdir command {} + - 类似 -exec command {} +,但以 文件所在目录 作为执行命令的工作目录
      • -fls file - 类似 -ls,但将输出写入指定文件
      • -fprint file - 将匹配文件路径输出到指定文件
      • -fprint0 file - 类似 -fprint,但使用 NULL 字符 (\0) 分隔
      • -fprintf file format - 按指定格式将结果写入文件
      • -ls - 以类似 ls -dils 的格式列出文件信息
      • -ok command ; - 类似 -exec,但在执行前会提示用户确认(y/n)
      • -okdir command ; - 类似 -execdir,但执行前会提示用户确认(y/n)
      • -print - 输出匹配文件路径;默认
      • -print0 - 输出文件路径,并以 NULL 字符分隔
      • -printf format - 按指定格式输出
      • -prune - 剪枝:如果文件是一个目录,则不要深入执行
      • -quit - 立即停止查找
    • Global options - 无论其在 EXPRESSION 中的什么位置,都会影响整个 EXPRESSION
      • -d - 同 -depth;用于 POSIX 兼容
      • -depth - 深度优先搜索
      • -files0-from file - 从指定文件中读取要搜索的起始路径列表,路径以 NULL 字符 (\0) 分隔
      • -help, --help - 显示帮助信息并退出
      • -ignore_readdir_race - 忽略在读取目录时发生的竞态条件错误
      • -maxdepth levels - 限制搜索的最大深度
      • -mindepth levels - 限制搜索的最小深度
      • -mount - 不要跨越文件系统
      • -noignore_readdir_race - 不忽略目录读取时的竞态条件错误
      • -noleaf - 禁用基于 Unix 目录结构的优化
      • -version, --version - 显示版本信息并退出
      • -xdev - 不跨越文件系统;同 -mount
    • Positional options - 只会影响 EXPRESSION 中在其之后出现的选项
      • -daystart - 将时间相关测试(如 -atime、-mtime、-ctime 等)的计算基准从“当前时间往前推 n×24 小时”改为“从今天的 00:00(当天开始)计算”。
      • -follow - 跟随符号链接(等同于 -L 选项)
      • -regextype type - 指定 -regex 和 -iregex 使用的正则表达式类型
        • emacs默认
        • posix-basic
        • posix-extended
        • awk
        • grep
        • egrep
      • -warn - 显示警告
      • -nowarn - 不显示警告
    • Operators - 操作符
      • ( expr ) - 提升优先级
      • ! expr, -not expr - 否运算
      • expr1 expr2, expr1 -a expr2, expr1 -and expr2 - 与运算;惰性求值
      • expr1 -o expr2, expr1 -or expr2 - 或运算;惰性求值
      • expr1 , expr2 - 分别执行 expr1expr2

#示例

递归设置目录权限

$ find path_to_dir -type d -exec chmod 775 {} + # 将 path_to_dir 里所有目录的权限设为 775
$ find path_to_dir -type f -exec chmod 664 {} + # 将 path_to_dir 里所有普通文件的权限设为 664
  • path_to_dir 里所有目录的权限设为 775
    • 所有者权限为 7 = 4 + 2 + 1 即可读、可写、可执行
    • 所属组权限为 5 = 4 + 1 即可读、可执行,不可写
    • 其他人权限为 5 = 4 + 1 即可读、可执行,不可写
  • path_to_dir 里所有普通文件的权限设为 664
    • 所有者权限为 7 = 4 + 2 + 1 即可读、可写、不可执行
    • 所属组权限为 4 即可读,不可写、不可执行
    • 其他人权限为 4 即可读,不可写、不可执行

#一、基础查找

#1. 按文件名查找
find /path -name "*.txt"

忽略大小写:

find /path -iname "*.txt"

#2. 查找指定文件
find / -name "config.json"

#3. 只查目录 / 文件
### 只查目录
find . -type d

### 只查普通文件
find . -type f

#二、按时间查找

#4. 按修改时间(mtime)
### 7 天内修改
find . -mtime -7

### 7 天前修改
find . -mtime +7

### 正好 7 天
find . -mtime 7

#5. 按访问时间(atime)
find . -atime -1   # 最近一天访问过

#6. 按分钟(更精细)
find . -mmin -30   # 30 分钟内修改

#三、按大小查找

### 大于 100MB
find . -size +100M

### 小于 10KB
find . -size -10k

### 正好 1GB
find . -size 1G

#四、按权限 / 用户

#7. 按权限
find . -perm 644

查找可执行文件:

find . -perm /111

#8. 按用户 / 组
find . -user root
find . -group www-data

#五、组合条件(重点)

#9. AND(默认就是 AND)
find . -type f -name "*.log"

#10. OR
find . -name "*.jpg" -o -name "*.png"

⚠️ 注意优先级问题:

find . \( -name "*.jpg" -o -name "*.png" \) -type f

#11. NOT
find . ! -name "*.txt"

#六、执行操作(核心能力)

#12. 删除文件
find . -name "*.tmp" -delete

#13. 使用 -exec
find . -name "*.log" -exec rm {} \;

优化(批量执行):

find . -name "*.log" -exec rm {} +

#14. 改权限
find . -type f -name "*.sh" -exec chmod +x {} +

#15. 移动文件
find . -name "*.jpg" -exec mv {} images/ \;

#七、结合 xargs(性能更好)

find . -name "*.log" | xargs rm

处理空格文件名(推荐):

find . -name "*.log" -print0 | xargs -0 rm

#八、搜索文件内容(很多人不知道)

#16. 使用 grep
find . -type f -name "*.txt" -exec grep "hello" {} +

更推荐:

grep -r "hello" .

#九、深度控制

#17. 限制深度
### 只查当前目录
find . -maxdepth 1

### 最少深度
find . -mindepth 2

#十、符号链接

### 查找符号链接
find . -type l

### 跟随链接
find -L . -name "*.txt"

#十一、高级技巧(非常实用)

#18. 查找空文件
find . -type f -empty

#19. 查找大目录
find . -type d -size +100M

#20. 查找最近修改的文件并排序
find . -type f -printf "%T@ %p\n" | sort -n

#21. 查找重复文件(结合 md5)
find . -type f -exec md5sum {} + | sort

#22. 查找没有扩展名的文件
find . -type f ! -name "*.*"

#23. 排除目录
find . -path "./node_modules" -prune -o -name "*.js" -print

#24. 查找最近修改的 10 个文件
find . -type f -printf "%T@ %p\n" | sort -nr | head -10

#十一、实战场景

#25. 删除 7 天前日志
find /var/log -name "*.log" -mtime +7 -delete

#26. 查找并压缩旧文件
find . -type f -mtime +30 -exec gzip {} +

#27. 查找代码文件中的 TODO
find . -name "*.js" -exec grep "TODO" {} +

#28. 查找大文件(前 20)
find . -type f -size +100M -exec ls -lh {} + | sort -k5 -h

#十二、常见坑(很重要)

#⚠️ 1. -o 优先级问题
### 错误
find . -name "*.js" -o -name "*.ts" -type f

### 正确
find . \( -name "*.js" -o -name "*.ts" \) -type f

#⚠️ 2. -exec 结尾必须有 \;+

#⚠️ 3. 文件名带空格

必须用:

-print0 | xargs -0

#⚠️ 4. -delete 很危险

建议先测试:

find . -name "*.tmp"

再加 -delete

#推荐阅读

#手册

更新: 2026/7/9

作者: planc

创建: 2026/4/8