find 命令详解
find用于在目录树中实时递归查找文件,并按条件执行动作。Linux 下通常是 GNU findutils,macOS/BSD 的find语法略有差异。
1. 基本语法
find [起始路径...] [表达式]起始路径:可写多个,省略时默认
.表达式:由测试、动作、运算符组成
如果表达式里没有动作,默认执行
-print
示例:
find . # 列出当前目录下所有文件/目录 find /var/log -type f # 只找普通文件 find . -name "*.txt" # 找 .txt 文件 find /etc/systemd -mindepth 3 -maxdepth 3 -path '/etc/systemd/*/*.wants/kysdk-conf2.service'2. 全局选项
find /path -maxdepth 2 -type f常用:
| 选项 | 说明 |
|---|---|
-maxdepth N | 最大递归深度 |
-mindepth N | 最小递归深度 |
-depth | 先处理目录内容,再处理目录本身 |
-xdev/-mount | 不跨越文件系统 |
-P | 默认,不跟随符号链接 |
-L | 跟随符号链接 |
-H | 只跟随命令行参数中的符号链接 |
注意:-maxdepth、-mindepth这类全局选项建议放在起始路径后、其他测试前。
3. 表达式逻辑
优先级从高到低:
( )分组!或-not取反-a或-and与,默认关系-o或-or或
示例:
find . -type f \( -name "*.c" -o -name "*.h" \) -print find . -type f ! -name "*.txt" find . -type f -name "*.log" -o -name "*.tmp"括号需要转义:\(\),避免被 shell 解释。
4. 常用测试条件
4.1 按名称/路径
find . -name "*.log" # 区分大小写,匹配文件名 find . -iname "*.jpg" # 忽略大小写 find . -path "*/log/*.log" # 匹配完整路径 find . -ipath "*/log/*.log" # 忽略大小写 find . -regex ".*\.(jpg|png)$"-name只匹配文件名部分-path匹配完整路径-regex默认是 Emacs 正则,可用-regextype posix-extended改
4.2 按类型
find . -type f # 普通文件 find . -type d # 目录 find . -type l # 符号链接常见类型:
| 类型 | 含义 |
|---|---|
f | 普通文件 |
d | 目录 |
l | 符号链接 |
b | 块设备 |
c | 字符设备 |
p | FIFO |
s | socket |
4.3 按大小
find . -type f -size +100M # 大于 100 MiB find . -type f -size -1k # 小于 1 KiB find . -type f -empty # 空文件或空目录单位:
c:字节k:KiBM:MiBG:GiB默认单位是 512 字节块
+表示大于,-表示小于,不写表示等于。
4.4 按时间
find . -type f -mmin -30 # 30 分钟内修改过 find . -type f -mtime -7 # 最近 7 天内修改过 find . -type f -mtime +7 # 超过 7 天未修改,通常为 8 天前及更早 find . -type f -newer /tmp/ref # 比 /tmp/ref 新 find . -newermt "2024-01-01" ! -newermt "2024-02-01"常见时间:
| 选项 | 含义 |
|---|---|
-atime | 访问时间 |
-mtime | 修改时间 |
-ctime | inode 状态改变时间,不是创建时间 |
-amin/-mmin/-cmin | 按分钟 |
-newer | 比指定文件新 |
-newermt | 比指定时间新 |
4.5 按权限
find . -type f -perm 644 # 权限精确为 644 find . -type f -perm -u+w # 用户写权限被设置,其他位不限 find . -type f -perm /o+w # 其他人写权限任意匹配 find . -type f -perm /222 # 任意写位被设置含义:
-perm mode:精确匹配-perm -mode:所有列出的权限位都必须设置-perm /mode:任意列出的权限位设置即可
4.6 按用户/组
find /home -user alice find /home -group dev find / -nouser find / -nogroup4.7 其他常用测试
find . -inum 12345 # 按 inode find . -links 2 # 硬链接数为 2 find . -samefile /path/file # 同一 inode find . -readable # 当前用户可读 find . -writable # 当前用户可写 find . -executable # 当前用户可执行5. 常用动作
5.1 打印
find . -print find . -print0 find . -ls-print0用 NUL 分隔,适合配合xargs -0处理特殊文件名。
5.2 格式化输出
find . -type f -printf "%TY-%Tm-%Td %TH:%TM %10s %p\n"常用格式:
| 格式 | 含义 |
|---|---|
%p | 完整路径 |
%f | 文件名 |
%h | 所在目录 |
%s | 大小 |
%m | 八进制权限 |
%M | 符号权限 |
%u | 用户 |
%g | 组 |
%y | 类型 |
%TY-%Tm-%Td | 修改日期 |
%TH:%TM | 修改时间 |
5.3 执行命令
每个文件执行一次:
find . -type f -name "*.log" -exec rm -f {} \;批量执行,更高效:
find . -type f -name "*.log" -exec rm -f {} +交互确认:
find . -type f -name "*.tmp" -ok rm -f {} \;在文件所在目录执行:
find . -type f -name "*.tmp" -execdir rm -f {} +5.4 删除
find /tmp -type f -mtime +7 -delete注意:-delete会自动启用-depth。使用前建议先-print确认:
find /tmp -type f -mtime +7 -print find /tmp -type f -mtime +7 -delete5.5 排除目录
find . \( -path "./.git" -o -path "./node_modules" \) -prune -o -type f -print含义:遇到.git或node_modules不进入,其他普通文件打印。
5.6 找到后退出
find . -type f -name "target.conf" -print -quit6. 典型示例
# 查找当前目录下所有 .log 文件 find . -type f -name "*.log" # 查找大于 1G 的文件 find / -xdev -type f -size +1G -printf "%s %p\n" | sort -nr | head # 查找最近 30 分钟修改过的文件 find . -type f -mmin -30 # 查找权限为 777 的文件 find . -type f -perm 777 # 查找并批量 grep find . -type f -name "*.c" -exec grep -l "main" {} + # 删除 7 天前的日志 find /var/log -type f -name "*.log" -mtime +7 -delete # 配合 xargs 处理特殊文件名 find . -type f -name "*.txt" -print0 | xargs -0 rm -f # 查找空目录并删除 find . -type d -empty -delete7. 注意事项
引号很重要
find . -name "*.txt"要加引号,否则*可能被 shell 提前展开。-name和-path不同-name只匹配文件名,-path匹配完整路径。-mtime +7不是精确第 7 天
它表示超过 7×24 小时,按整天取整后通常匹配 8 天前及更早。-exec ... +比-exec ... \;高效
前者会批量传参,减少进程创建次数。删除操作先打印
先运行-print确认结果,再换成-delete或-exec rm。符号链接默认不跟随
默认-P,不跟随符号链接;需要跟随时用-L,但可能遇到循环。文件名含空格/换行
用-print0配合xargs -0,不要直接用-print | xargs。性能优化
尽量缩小起始路径,使用-maxdepth、-type f、-xdev,避免从/全盘扫描。
8. 速查
find 起点 [选项] [测试] [动作] find . -type f -name "*.txt" find . -type d -name "build" find . -size +100M find . -mtime +7 find . -perm /o+w find . -user alice find . -empty find . -name ".git" -prune -o -print find . -type f -exec rm {} \; find . -type f -exec rm {} + find . -type f -print0 | xargs -0 rm -f find . -type f -printf "%p %s\n"一句话:find的核心是从起点递归遍历,用表达式组合测试条件,再对匹配文件执行动作。