Linux find 进阶:按时间、大小和权限组合筛选文件
Linux find 命令的高级用法,核心不是记更多参数,而是学会把多个筛选条件组合起来,先缩小范围再执行动作。
下面按实际运维中最常见的场景展开:按时间找旧日志、按大小找大文件、按权限找异常文件,以及用 -exec 和 xargs 批量处理。
先确认环境和基本语法
find 在绝大多数 Linux 发行版中默认自带,一般不需要单独安装。
先用 find --version 确认可用。
基本结构是:
find 搜索路径 筛选条件 执行动作
不写动作时,默认只把匹配到的路径打印出来。
建议所有删除、改权限类操作,先去掉动作跑一遍,确认结果符合预期再补上动作。
按时间和大小缩小范围
查找修改时间超过 30 天的普通文件:
find /var/log -type f -mtime +30
-mtime +30 表示修改时间在 30 天以前,-type f 限定只找普通文件,避免把目录也列出来。
查找大于 500MB 的文件:
find /data -type f -size +500M
单位 M 表示兆字节,+ 表示大于,- 表示小于。
如果要精确匹配某个大小,直接写 -size 100M。
把两个条件组合,找出 /data 下超过 500MB 且 7 天未修改的文件:
find /data -type f -size +500M -mtime +7
多个条件并列时默认是“与”关系,即同时满足。
按权限和目录深度定位异常文件
服务器上排查安全问题时,常需要找权限过于宽松的文件。
查找权限为 777 的文件:
find /var/www -type f -perm 777
如果只想在当前目录下一层查找,不递归进子目录,用 -maxdepth:
find /var/www -maxdepth 1 -type f -perm 777
-maxdepth 1 表示最多向下查一层,-maxdepth 2 就是两层。
这个参数对目录层级很深的站点特别有用,能明显减少无关结果。
用 -exec 和 xargs 批量处理
找到旧日志后直接删除,是 find 最常用的动作之一:
find /var/log -type f -name "*.log" -mtime +30 -delete
-delete 是 find 自带的删除动作,比管道传给 rm 更稳妥,因为它只删除 find 已经确认匹配到的文件。
如果要对匹配结果执行其他命令,用 -exec:
find /var/www -type f -name "*.php" -exec chmod 644 {} \;
{} 代表当前匹配到的文件,\; 表示命令结束。
注意分号前的反斜杠不能省,否则会被 shell 提前解释。
当匹配文件很多时,-exec ... + 或 xargs 效率更高:
find /var/www -type f -name "*.php" -exec chmod 644 {} +
+ 会把多个文件一次性传给命令,减少进程启动次数。
用 xargs 的等价写法是:
find /var/www -type f -name "*.php" -print0 | xargs -0 chmod 644
-print0 和 -0 配合,用空字符分隔文件名,能正确处理带空格或特殊字符的路径。
容易踩坑的地方
第一,删除或改权限前一定先不加动作跑一遍,把结果重定向到文件里核对:
find /data -type f -size +500M > /tmp/bigfiles.txt
确认 /tmp/bigfiles.txt 内容无误后再执行删除。
第二,-mtime、-mmin 这类时间参数对“天”和“分钟”的边界容易记混,-mtime +7 是 7 天以前,不是最近 7 天,最近 7 天要用 -mtime -7。
第三,不要对根目录 / 直接执行带删除动作的 find,一旦条件写错影响面很大。
先在具体业务目录内测试,再扩大到需要清理的范围。
第四,-name 区分大小写,-iname 不区分。
找 *.LOG 和 *.log 时用 -iname 更省事。
怎么验证结果是对的
执行完删除或改权限后,用同样条件再跑一次 find,预期输出应该为空或只剩符合条件的新文件。
改权限后可以抽查:
find /var/www -type f -name "*.php" -exec ls -l {} \;
看输出中的权限位是否已经变成目标值。
如果是清理磁盘,再用 df -h 确认对应分区可用空间确实下降。
常见疑问
find 和 locate 有什么区别?
locate 依赖预先建立的文件索引,速度快但结果可能不是实时的;
find 是实时遍历目录,结果准确但大目录下更慢。
需要精确结果时用 find。
为什么 find 报 Permission denied?
一般是当前用户对某些目录没有读取权限。
可以在命令末尾加 2>/dev/null 屏蔽无权限的报错,或者用 sudo 提权,但要清楚提权后动作的影响范围。
-exec 后面的 \; 和 + 怎么选?
只处理少量文件、需要逐个执行时用 \;;
文件数量多、想合并成一批执行时用 +,后者通常更快。
掌握按时间、大小、权限、深度组合筛选,再加上安全的批量处理写法,find 就能覆盖日志清理、磁盘排查和权限修复这几类高频运维场景。
建议先在测试目录完整跑通一遍,再应用到生产环境。