find命令高级用法:批量文件操作的神器

find是Linux下最强大的文件查找命令,但很多人只会最基本的用法。

这篇整理一些进阶技巧,让find真正成为你的效率工具。


基础回顾

# 基本格式
find [路径] [条件] [动作]

# 按名字找
find /var/log -name "*.log"

# 按类型找
find /home -type f    # 普通文件
find /home -type d    # 目录
find /home -type l    # 符号链接

# 按大小找
find /var -size +100M   # 大于100M
find /var -size -1k     # 小于1k
find /tmp -size 0       # 空文件

这些基础用法大家都会,下面讲进阶的。


时间条件

find的时间条件有三种:

  • -mtime:修改时间(内容变化)
  • -atime:访问时间(读取文件)
  • -ctime:状态变化时间(权限、属主等)
# 7天内修改的文件
find /data -mtime -7

# 7天前修改的文件
find /data -mtime +7

# 恰好7天前修改的文件
find /data -mtime 7

# 24小时内修改的
find /data -mtime 0

更精确的用-mmin(分钟):

# 60分钟内修改的
find /var/log -mmin -60

# 超过60分钟没访问的
find /tmp -amin +60

实用场景

# 清理7天前的日志
find /var/log -name "*.log" -mtime +7 -delete

# 找最近1小时改动的配置文件
find /etc -name "*.conf" -mmin -60

# 找从没被访问过的文件(atime等于mtime通常意味着创建后没访问)
find /data -type f -atime +30

权限和属主

# 按权限找
find /home -perm 777         # 精确匹配777
find /home -perm -644        # 至少有644权限
find /home -perm /111        # 任意用户有执行权限

# 按属主找
find /var -user root
find /var -user 1000         # 用UID也行
find /var -nouser            # 没有属主的文件(用户被删了)

# 按属组找
find /var -group www
find /var -nogroup           # 没有属组的文件

安全检查场景

# 找777权限的文件(安全隐患)
find /var/www -type f -perm 777

# 找SUID文件(安全审计)
find / -perm -4000 -type f 2>/dev/null

# 找SGID文件
find / -perm -2000 -type f 2>/dev/null

# 找无主文件
find / -nouser -o -nogroup 2>/dev/null

组合条件

逻辑运算

# AND(默认)
find /data -name "*.log" -size +10M
# 相当于
find /data -name "*.log" -a -size +10M

# OR
find /data -name "*.log" -o -name "*.txt"

# NOT
find /data ! -name "*.log"

# 复杂组合(用括号,要转义)
find /data \( -name "*.log" -o -name "*.txt" \) -mtime -7

实用组合

# 找大于100M且7天没访问的文件
find /data -type f -size +100M -atime +7

# 找空目录
find /data -type d -empty

# 找空文件
find /data -type f -empty

# 找非空的log文件
find /var/log -type f -name "*.log" ! -empty

# 找可执行的脚本
find /usr/local/bin -type f -perm /111 -name "*.sh"

限制搜索深度

# 只搜索当前目录,不递归
find /data -maxdepth 1 -type f

# 限制深度为2层
find /home -maxdepth 2 -name "*.conf"

# 从第2层开始搜索
find /data -mindepth 2 -name "*.log"

# 只搜索第2层
find /data -mindepth 2 -maxdepth 2 -name "*.log"

限制深度能大幅提升搜索速度,特别是目录很深的情况。


执行动作

-exec 执行命令

# 基本格式
find ... -exec command {} \;

# 删除7天前的日志
find /var/log -name "*.log" -mtime +7 -exec rm {} \;

# 修改权限
find /var/www -type f -exec chmod 644 {} \;
find /var/www -type d -exec chmod 755 {} \;

# 查看文件详情
find /data -name "*.conf" -exec ls -l {} \;

# 批量移动
find /tmp -name "*.tmp" -exec mv {} /backup/ \;

{} 代表找到的文件,\; 表示命令结束。

-exec 的 + 结尾(批量)

# \; 是每个文件执行一次命令
find /data -name "*.log" -exec ls -l {} \;
# 相当于执行了N次 ls -l

# + 是合并成一次执行
find /data -name "*.log" -exec ls -l {} +
# 相当于 ls -l file1 file2 file3 ...

# + 更高效,能用就用
find /data -name "*.txt" -exec cat {} + > all.txt

-delete 直接删除

# 比 -exec rm {} \; 更快更安全
find /tmp -name "*.tmp" -mtime +7 -delete

# 注意:-delete 只能删文件,删目录要先删里面的
find /data -type f -name "*.bak" -delete
find /data -type d -empty -delete

-print0 + xargs(处理特殊文件名)

# 文件名有空格或特殊字符时,用 -print0
find /data -name "*.log" -print0 | xargs -0 rm

# 批量grep
find /src -name "*.java" -print0 | xargs -0 grep "TODO"

# 批量处理
find /data -type f -print0 | xargs -0 -I {} cp {} /backup/

-print0 用 null 字符分隔,能正确处理空格和换行符。


实战场景

1. 清理磁盘空间

# 找大文件
find / -type f -size +1G 2>/dev/null | head -20

# 找并显示大小,按大小排序
find /data -type f -size +100M -exec ls -lh {} \; | sort -k5 -h

# 清理各种临时文件
find /tmp -type f -atime +7 -delete
find /var/log -name "*.gz" -mtime +30 -delete
find /data -name "*.bak" -mtime +7 -delete

# 清理空目录
find /data -type d -empty -delete

2. 批量重命名

# 把 .txt 改成 .md
find /data -name "*.txt" -exec bash -c 'mv "$0" "${0%.txt}.md"' {} \;

# 文件名转小写
find /data -type f -exec bash -c 'mv "$0" "$(dirname "$0")/$(basename "$0" | tr A-Z a-z)"' {} \;

# 加前缀
find /data -name "*.log" -exec bash -c 'mv "$0" "$(dirname "$0")/backup_$(basename "$0")"' {} \;

3. 代码搜索

# 在所有Java文件中搜索
find /src -name "*.java" -exec grep -l "deprecated" {} +

# 统计代码行数
find /src -name "*.py" -exec wc -l {} + | tail -1

# 找包含TODO的文件
find /src \( -name "*.java" -o -name "*.py" \) -exec grep -l "TODO" {} +

# 找最近修改的代码文件
find /src -name "*.go" -mtime -1

4. 权限修复

# 批量修复权限
find /var/www -type d -exec chmod 755 {} +
find /var/www -type f -exec chmod 644 {} +

# 可执行文件加执行权限
find /usr/local/bin -type f -name "*.sh" -exec chmod +x {} +

# 修复属主
find /var/www -type f -exec chown www:www {} +

5. 备份特定文件

# 备份最近修改的配置
find /etc -name "*.conf" -mtime -7 -exec cp --parents {} /backup/ \;
# --parents 保持目录结构

# 打包特定文件
find /data -name "*.log" -mtime -1 -print0 | tar cvzf backup.tar.gz --null -T -

6. 统计分析

# 按扩展名统计文件数量
find /data -type f | sed 's/.*\.//' | sort | uniq -c | sort -rn

# 按目录统计文件大小
find /data -maxdepth 1 -type d -exec du -sh {} \; | sort -h

# 统计最近7天新增的文件
find /data -type f -mtime -7 | wc -l

性能优化

1. 限制深度

# 不要无脑从根目录搜
find / -name "xxx" 2>/dev/null        # 慢
find /var/log -name "xxx"              # 快

2. 避免不必要的目录

# 排除某些目录
find / -path "/proc" -prune -o -name "*.conf" -print
find / -path "/sys" -prune -o -path "/proc" -prune -o -name "xxx" -print

# 更直观的写法
find /home -name ".git" -prune -o -name "*.java" -print

3. 用 + 代替 ;

# 慢
find /data -name "*.log" -exec ls -l {} \;

# 快
find /data -name "*.log" -exec ls -l {} +

4. 利用locate

如果只是找文件位置,locatefind快得多:

# 先更新数据库
updatedb

# 快速查找
locate nginx.conf

locate用的是数据库,不是实时的。


常见坑

1. 路径问题

# 当前目录要写 .
find . -name "*.log"       # 对
find -name "*.log"         # 也行,默认当前目录
find "-name" "*.log"       # 错!-name被当成路径了

2. 引号问题

# 通配符要加引号
find /data -name *.log     # 错!shell先展开了
find /data -name "*.log"   # 对
find /data -name '*.log'   # 也对

3. -delete 的位置

# -delete 要放在条件后面
find /tmp -delete -name "*.tmp"   # 危险!会删除/tmp下所有文件
find /tmp -name "*.tmp" -delete   # 正确

4. 权限错误

# 忽略权限不足的错误
find / -name "xxx" 2>/dev/null
find / -name "xxx" 2>&1 | grep -v "Permission denied"

速查表

# 按名字
-name "*.log"      # 精确匹配(大小写敏感)
-iname "*.log"     # 忽略大小写

# 按类型
-type f            # 文件
-type d            # 目录
-type l            # 链接

# 按大小
-size +100M        # 大于
-size -1k          # 小于
-empty             # 空

# 按时间
-mtime -7          # 7天内修改
-mtime +7          # 7天前修改
-mmin -60          # 60分钟内

# 按权限
-perm 644          # 精确匹配
-perm -644         # 至少有
-user root         # 属主

# 逻辑
-a                 # AND
-o                 # OR
!                  # NOT

# 动作
-print             # 打印(默认)
-delete            # 删除
-exec cmd {} \;    # 执行命令
-exec cmd {} +     # 批量执行

# 深度
-maxdepth N        # 最大深度
-mindepth N        # 最小深度

总结

find的核心套路:

  1. 先定位置:尽可能缩小搜索范围
  2. 再加条件:名字、类型、大小、时间、权限
  3. 最后动作:打印、删除、执行命令

几个常用组合记住就行:

# 找大文件
find /data -type f -size +100M

# 清理旧日志  
find /var/log -name "*.log" -mtime +7 -delete

# 批量改权限
find /var/www -type f -exec chmod 644 {} +

# 批量搜索内容
find /src -name "*.java" -exec grep -l "keyword" {} +

有问题评论区聊。


posted @ 2025-12-30 12:10  花宝宝  阅读(3)  评论(0)    收藏  举报