一、作用
find 是 Linux 系统中强大的文件查找工具,可以在指定目录中递归搜索文件和目录,根据名称、类型、大小、时间、权限等条件进行筛选,还能对找到的文件执行各种操作。
二、基本语法
bash
find [路径...] [表达式]
- 路径:搜索的起始目录(可指定多个),默认当前目录。
- 表达式:由选项、测试、动作和操作符组成,用于定义搜索条件和后续操作。
默认行为 :如果没有指定表达式,find 会自动添加 -print 动作。
2.1 选项(Options)
选项控制 find 的整体行为,通常放在其他表达式之前:
| 选项 | 说明 | 示例 |
|---|---|---|
-maxdepth N |
最大搜索深度 | find . -maxdepth 2 -name "*.conf" |
-mindepth N |
最小搜索深度 | find /usr -mindepth 2 -name "*.so" |
-depth |
深度优先处理 | find . -depth -name "*.tmp" -delete |
-follow |
跟随符号链接 | find -L . -name "target" |
-mount 或 -xdev |
不跨越文件系统 | find / -xdev -name "core" 2>/dev/null |
-daystart |
从今天开始计算时间 | find . -daystart -mtime -1 |
-regextype TYPE |
指定正则表达式类型 | `find . -regextype posix-extended -regex ".*.(jpg |
2.2 测试(Tests)
测试是 find 命令的核心,用于筛选文件。
- 文件名测试
bash
# 基本名称匹配
find . -name "config.txt" # 精确匹配
find . -iname "CONFIG.TXT" # 不区分大小写
# 通配符匹配
find . -name "*.log" # 所有日志文件
find . -name "file[0-9].txt" # file1.txt, file2.txt等
# 路径匹配
find /usr -path "*/bin/*" # 匹配路径中包含/bin/的文件
- 文件类型测试
bash
find . -type f # 普通文件(file)
find . -type d # 目录(directory)
find . -type l # 符号链接(link)
find . -type s # 套接字(socket)
find . -type p # 命名管道(pipe)
find . -type b # 块设备(block device)
find . -type c # 字符设备(character device)
- 时间测试
bash
# 修改时间(mtime)
find . -mtime -7 # 7天内修改过
find . -mtime +30 # 30天前修改过
find . -mtime 0 # 24小时内修改过
# 访问时间(atime)
find . -atime -1 # 1天内访问过
# 状态改变时间(ctime)
find . -ctime +60 # 60天前状态改变过
# 按分钟计算
find . -mmin -30 # 30分钟内修改过
- 大小测试
bash
find . -size +100M # 大于100MB
find . -size -1k # 小于1KB
find . -size 0 # 空文件
find . -empty # 空文件或空目录
- 权限测试
bash
# 精确权限匹配
find . -perm 644 # 权限正好是644
# 至少包含这些权限
find . -perm -u=x # 用户可执行
find . -perm -g=w # 组可写
# 任意匹配这些权限
find . -perm /o=x # 其他人可执行
# 可读/写/执行测试
find . -readable # 当前用户可读
find . -writable # 当前用户可写
find . -executable # 当前用户可执行
- 用户/组测试
bash
find . -user root # root用户的文件
find . -group users # users组的文件
find . -nouser # 无有效用户的文件
find . -nogroup # 无有效组的文件
- 其他测试
bash
find . -links 2 # 有2个硬链接
find . -inum 12345 # inode号为12345
find . -newer file.txt # 比file.txt新
find . -regex ".*\.log$" # 正则表达式匹配
2.3 动作(Actions)
动作指定找到文件后要执行的操作:
| 动作 | 说明 | 示例 |
|---|---|---|
-print |
打印文件路径(默认动作) | find . -name "*.txt" |
-print0 |
以null字符分隔输出 | `find . -name "*.txt" -print0 |
-ls |
显示详细信息 | find . -name "*.conf" -ls |
-delete |
删除文件 | find . -name "*.swp" -delete |
-exec |
执行命令 | find . -name "*.log" -exec gzip {} \; |
-exec {} + |
批量执行命令 | find . -name "*.jpg" -exec cp {} /backup/ + |
-ok |
交互式执行 | find . -name "*.bak" -ok rm {} \; |
-printf |
格式化输出 | find . -printf "%p - %s bytes\n" |
-prune |
跳过目录 | find . -name ".git" -prune -o -print |
-quit |
找到第一个匹配后退出 | find / -name "passwd" -print -quit |
2.4 操作符(Operators)
操作符连接多个测试,控制逻辑关系:
| 操作符 | 说明 | 示例 |
|---|---|---|
空格 或 -a |
与(AND) | find . -name "*.txt" -size +1k |
-o |
或(OR) | find . -name "*.jpg" -o -name "*.png" |
! 或 -not |
非(NOT) | find . ! -name "*.tmp" |
( ) |
括号分组 | find . \( -name "*.c" -o -name "*.h" \) |
, |
顺序执行 | find . -print , -name "*.txt" -print |
三、常用示例
| 需求 | 命令示例 |
|---|---|
| 按名称查找 | find . -name "*.txt" |
| 按类型查找 | find . -type f(文件) find . -type d(目录) |
| 按时间查找 | find . -mtime -7(7天内修改) find . -atime +30(30天前访问) |
| 按大小查找 | find . -size +100M(大于100MB) find . -size -1k(小于1KB) |
| 按权限查找 | find . -perm 644(权限644) find . -executable(可执行文件) |
| 查找空文件 | find . -type f -empty |
| 查找并删除 | find . -name "*.tmp" -delete |
| 查找并执行 | find . -name "*.sh" -exec chmod +x {} \; |
| 排除目录 | find . -name ".git" -prune -o -print |
| 限制深度 | find . -maxdepth 2 -name "*.conf" |
| 批量重命名 | find . -name "*.htm" -exec rename 's/\.htm$/.html/' {} \; |
四、常用技巧
4.1 文件清理
bash
# 清理临时文件
find /tmp -type f -atime +1 -delete
find ~/.cache -type f -mtime +7 -delete
# 查找并删除空文件
find . -type f -empty -delete
# 清理旧日志(保留最近30天)
find /var/log -name "*.log" -mtime +30 -delete
4.2 查找特定内容
bash
# 在所有.py文件中查找import语句
find . -name "*.py" -exec grep -l "import pandas" {} \;
# 查找包含密码的配置文件
find /etc -type f -name "*.conf" -exec grep -l "password" {} \;
# 统计代码行数
find src -name "*.java" -type f -exec wc -l {} +
4.3 系统管理
bash
# 查找大文件(前10名)
find / -type f -size +100M 2>/dev/null | xargs ls -lh | sort -k5,5hr | head -10
# 查找SUID/SGID文件(安全审计)
find / -type f \( -perm -4000 -o -perm -2000 \) 2>/dev/null -ls
# 查找所有人可写的文件(安全隐患)
find /home -type f -perm -o=w ! -type l
4.4 批量操作
bash
# 批量重命名
find . -name "*.htm" -exec bash -c 'mv "$1" "${1%.htm}.html"' _ {} \;
# 批量修改权限
find /var/www -type f -name "*.php" -exec chmod 644 {} \;
find /var/www -type d -exec chmod 755 {} \;
# 批量备份
find /data -type f -mtime 0 -exec cp {} /backup/ \;
4.5 排除特定内容
bash
# 排除.git目录
find . -name ".git" -prune -o -type f -print
# 排除多个目录
find /project \( -name ".git" -o -name "node_modules" \) -prune -o -type f -print
# 排除隐藏文件
find . ! -name ".*" -type f
五、进阶用法
5.1 格式化输出
bash
# 自定义输出格式
find . -type f -printf "文件: %-50p 大小: %10s 修改时间: %t\n"
# 生成HTML报告
echo "<html><body><h1>文件列表</h1><ul>" > report.html
find . -type f -printf '<li><a href="%p">%f</a> (%s bytes)</li>\n' >> report.html
echo "</ul></body></html>" >> report.html
# 输出到不同文件
find . -type f -name "*.py" -fprint python_files.txt -o -name "*.js" -fprint js_files.txt
5.2 处理特殊文件名
bash
# 安全处理包含空格、换行的文件名
find . -name "* *" -print0 | xargs -0 rm
# 或使用-exec ... +
find . -name "* *" -exec rm {} +
# 避免shell解释通配符
find . -name "*.log" # 正确
find . -name *.log # 错误(如果当前目录有.log文件)
5.3 性能优化
bash
# 限制搜索深度
find . -maxdepth 3 -name "*.conf" # 只搜索3层目录
# 将常见测试放前面
find . -name "*.log" -size +1M -exec gzip {} \; # 高效
find . -exec gzip {} \; -name "*.log" -size +1M # 低效
# 使用locate加速(需先更新数据库)
updatedb && locate "*.conf"
5.4 条件判断
bash
# 使用条件判断
find . -type f -name "*.txt" -exec sh -c '
if [ -s "$1" ]; then
echo "非空文件: $1"
else
echo "空文件: $1"
fi
' _ {} \;
# 根据文件大小执行不同操作
find . -type f -exec sh -c '
if [ $(stat -c %s "$1") -gt 1048576 ]; then
echo "大文件: $1"
else
echo "小文件: $1"
fi
' _ {} \;
5.6 处理权限错误
bash
# 忽略权限错误
find / -name "passwd" 2>/dev/null
# 将错误重定向到文件
find / -name "*.conf" > found_files.txt 2>errors.txt
# 同时显示错误和正常输出
find / -name "*.conf" 2>&1 | grep -v "Permission denied"
5.7 调试复杂命令
bash
# 使用echo先测试
find . -name "*.tmp" -exec echo "将删除: {}" \;
# 逐步构建复杂命令
find . -type f
find . -type f -name "*.log"
find . -type f -name "*.log" -size +1M
find . -type f -name "*.log" -size +1M -exec echo "压缩: {}" \;
find . -type f -name "*.log" -size +1M -exec gzip {} \;
5.8 验证结果
bash
# 先查看再操作
find . -name "*.bak" -print # 先查看哪些文件会被影响
find . -name "*.bak" -delete # 确认无误后再删除
# 使用交互模式
find . -name "important_*" -ok rm {} \; # 每个文件都询问确认