从入门到实战 | 10 个经典案例 + 3 种组合技
在 Linux 系统管理中,find 是「四剑客」中专门负责文件查找的一员猛将。无论是按名称、大小、时间还是权限,find 都能精准定位你要的文件。本文将从基础语法讲到高级组合技,配合真实案例,帮你彻底掌握这把利器。
一、find 命令概览
find 的基本语法非常直观:
find [搜索路径] [选项] [表达式]
核心选项一览:
| 选项 | 作用 | 常用示例 |
|---|
-type | 指定文件类型 | f 文件 / d 目录 / l 链接 |
-name | 按文件名匹配(区分大小写) | -name '*.conf' |
-iname | 按文件名匹配(不区分大小写) | -iname '*.CONF' |
-size | 按文件大小查找 | +10k / -10M / +1G |
-mtime | 按修改时间查找 | +7 7天前 / -7 最近7天 |
-maxdepth | 限制搜索目录深度 | -maxdepth 2 |
-user | 按文件所有者查找 | -user root |
-perm | 按权限查找 | -perm 755 / -perm /u+x |
大小单位注意:k 是小写(KB),M 是大写(MB),G 是大写(GB)。这是初学者最容易搞混的地方。
二、基础案例:精准定位文件
案例 1:精确查找
在 /etc/ 目录中找到名为 hostname 的文件:
find /etc/ -type f -name'hostname'# 输出:/etc/hostname
案例 2:模糊查找(通配符)
找出 /etc/ 下所有 .conf 结尾的文件:
find /etc/ -type f -name'*.conf'
通配符技巧:
案例 3:按大小查找
找出 /etc/ 目录下大于 10KB 的文件:
find /etc/ -type f -size+10k
可以同时指定多个搜索路径:
find /etc/ /tmp/ -type f -size+10k
案例 4:按修改时间查找
这是日常运维中清理旧日志的高频操作:
# 找出 /etc/ 下 7 天之前修改的 .conf 文件find /etc/ -type f -name"*.conf"-mtime+7# 找出最近 7 天内修改的文件find /data/ -type f -mtime-7# 找出 7 天之前的文件find /data/ -type f -mtime+7
-mtime 的时间线:
+7 = 修改时间在 7 天之前(更旧的文件)
-7 = 修改时间在最近 7 天内(更新的文件)
7 = 恰好 7 天前那一天修改的文件
案例 5:多条件组合
找出 /etc/ 中以 .conf 结尾、大于 10KB、且 7 天之前修改的文件:
find /etc/ -type f -name'*.conf'-size+10k -mtime+7# 输出示例:/etc/rc.conf
验证一下:
ls -lh /etc/rc.conf# -rw-r--r--. 1 root root 94K Oct 1 2023 /etc/rc.conf
多个条件直接叠加,默认就是 AND(与) 关系——所有条件同时满足才会被选中。
三、进阶选项
案例 6:限制搜索深度
搜索根目录下所有 .conf 文件,但只找前两层目录:
find / -maxdepth2 -type f -name"*.conf"
注意:-maxdepth 必须放在其他选项之前(紧跟搜索路径之后),否则 find 会给出警告。不加此选项则默认搜索所有层级。
案例 7:不区分大小写
# -iname = ignore casefind / -type f -iname"*.conf"
补充:按用户和权限查找
# 查找属于 www 用户的文件find /var/www/ -type f -user www# 查找权限为 777 的文件(安全排查常用)find / -type f -perm777# 查找具有 SUID 位的可执行文件find / -type f -perm /4000
补充:逻辑运算符
find 支持 -o(OR)、!(NOT)、-a(AND)逻辑组合:
# 查找 .conf 或 .cfg 结尾的文件find /etc/ -type f \( -name'*.conf'-o-name'*.cfg' \)# 查找不以 .log 结尾的文件find /var/log/ -type f ! -name'*.log'
补充:其他时间选项
| 选项 | 说明 |
|---|
-mtime | 按内容修改时间(最常用) |
-atime | 按访问时间 |
-ctime | 按属性变更时间(权限、所有者等) |
-mmin | 按分钟计的修改时间,如 -mmin -30 最近30分钟 |
-newer file | 比指定文件更新的文件 |
四、组合技:find 与其他命令配合
这是 find 的难点和精华所在。find 找出文件后,如何传递给其他命令处理?有三种核心方法。
先准备实验环境:
mkdir -p /tmp/demotouch /tmp/demo/file{01..10}.txt方法一:反引号 / $() 命令替换
这是最直观的方式——先执行 find,再把结果作为参数传给其他命令:
# 查看文件详细信息(反引号写法)ls -lh `find /tmp/demo/ -type f -name '*.txt'`# 推荐用 $() 代替反引号,可读性更好、支持嵌套ls -lh $(find /tmp/demo/ -type f -name '*.txt')
方法二:管道 + xargs
先来看一个常见错误:
# ❌ 错误写法:管道传递的是字符串,但 ls 需要的是参数find /tmp/demo/ -type f -name'*.txt' | ls-lh# find 的结果被丢弃了,等于只执行了 ls -lh# ✅ 正确写法:xargs 把字符串转换为命令参数find /tmp/demo/ -type f -name'*.txt' | xargs ls-lh
管道的秘密:
管道 | 把前一个命令的标准输出作为字符串传给后一个命令的标准输入。但像 ls、cp、rm 这类命令并不从标准输入读取参数——它们只认命令行参数。
xargs 的作用就是把标准输入的字符串转换为命令行参数,充当"翻译官"。
方法三:-exec
find /tmp/demo/ -type f -name'*.txt'-execls-lh {} \;语法说明:
提醒: find 不要与交互式命令配合,比如 find + vi/vim 是错误用法。
五、实战案例:打包、复制、删除
案例 8:find + 打包压缩
将 find 找出的文件打包成 tar.gz:
# 方法一:命令替换tar zcf /tmp/demo.tar.gz $(find /tmp/demo/ -type f -name '*.txt')# 方法二:xargsfind /tmp/demo/ -type f -name'*.txt' | xargs tar zcf /tmp/demo.tar.gz
-exec 打包的坑:
find ... -exec tar zcf xxx.tar.gz {} \; 会对每个文件单独执行一次 tar,后面的压缩包会覆盖前面的,最终只有最后一个文件。
解决: 把 \; 换成 +,表示把所有文件一次性传给 tar:
find /tmp/demo/ -type f -name'*.txt'-exec tar zcf /tmp/demo.tar.gz {} +
案例 9:find + 复制/移动
# 方法一:命令替换cp $(find /tmp/demo/ -type f -name '*.txt') /tmp/backup/# 方法二:xargs(注意 cp -t 参数顺序)find /tmp/demo/ -type f -name'*.txt' | xargs cp-t /tmp/backup/# 方法三:-execfind /tmp/demo/ -type f -name'*.txt'-execcp {} /tmp/backup/ \;为什么 xargs + cp 需要 -t ?
xargs 默认将参数追加到命令末尾,所以 find ... | xargs cp /tmp/backup/ 实际执行的是 cp /tmp/backup/ file1 file2 ...,语义变成了「把 /tmp/backup/ 复制到 file2」——完全反了。
cp -t /tmp/backup/ 用 -t 显式指定目标目录,后面追加的参数自然就是源文件,逻辑正确。
案例 10:find + 删除旧日志
这是运维中最常见的 find 应用场景:
# 删除 30 天之前的日志文件find /var/log/app/ -type f -name'*.log'-mtime+30-delete# 或者用 xargs + rmfind /var/log/app/ -type f -name'*.log'-mtime+30 | xargs rm-f
安全警告: 执行删除操作前,务必先把 rm 换成 ls -l 确认文件列表没有问题,避免误删!
六、补充知识:处理特殊文件名
当文件名包含空格或特殊字符时,前面的方法都可能出问题。最安全的做法:
# 用 -print0 输出以 null 分隔的文件名# 用 xargs -0 以 null 作为分隔符读取find /data/ -type f -name'*.txt'-print0 | xargs -0rm-f
-print0 + xargs -0 是处理含空格文件名的标准组合,建议养成习惯。
七、三种方法对比
| 方法 | 写法 | 优点 | 缺点 |
|---|
| 反引号 / $() | cmd $(find ...) | 语法直观,易于理解 | 文件名含空格会出错;文件过多时参数列表超长报错 |
| | xargs | find ... \| xargs cmd | 高效,自动分批处理;支持 -0 处理特殊字符 | 需注意参数位置(如 cp -t) |
| -exec | find ... -exec cmd {} \; | find 原生支持,无需额外命令 | 每个文件执行一次命令,效率较低(用 + 替代 \; 可解决) |
推荐优先级: xargs > $() > -exec
xargs 兼顾效率和安全性,配合 -0 几乎无死角。
八、注意事项
不要与交互式命令配合:find + vi/vim 是错误用法,vi 需要交互式终端。
-maxdepth 放在最前面:它必须出现在其他测试选项之前,否则会收到警告。
通配符要加引号:-name *.conf 可能被 Shell 提前展开,必须写成 -name '*.conf'。
大范围搜索加深度限制:在 / 下搜索不加 -maxdepth 会遍历整个文件系统,耗时很长。
删除前先确认:任何 find + delete/rm 操作,先用 ls -l 替代 rm 预览结果。
排除目录用 -prune:find / -path /proc -prune -o -type f -name '*.conf' -print 可以跳过 /proc 目录。
全文速查
精确查找:find /path -type f -name 'filename'
模糊匹配:-name '*.conf' / '*keyword*'
按大小:-size +10k / -size -1M
按时间:-mtime +7(7天前)/ -mtime -7(最近7天)
限制深度:-maxdepth N(放在最前面)
忽略大小写:-iname 替代 -name
按用户:-user username
按权限:-perm 755 / -perm /4000
组合命令:优先用 xargs,注意 -print0 / -0 处理特殊文件名
逻辑组合:-a(AND)、-o(OR)、!(NOT)
写在最后
本文覆盖了 find 命令 90% 的日常使用场景:
按名称/大小/时间/权限/用户等多维度精准定位文件
三种组合技($()、xargs、-exec)让 find 与任意命令协作
管道传参的底层原理,搞懂 xargs 为什么不可或缺
特殊文件名的安全处理(-print0 + xargs -0)
6 条避坑指南,帮你绕开生产环境的常见事故
find 只是 Linux 四剑客的其中一位。 接下来还有:
grep — 文本内容过滤,日志排查的第一利器
sed — 流编辑器,批量替换文本的瑞士军刀
awk — 列处理专家,文本报表信手拈来
关注本公众号,四剑客系列将逐篇更新,带你从入门到生产实战,每篇都是拿来就能用的干货。
觉得有用?转发给你的运维/开发同事,一起提效。