在Linux系统中,查找文件是日常高频操作。今天我们就来聊聊两个经典的查找工具:locate和find。前者像懒人神器,后者像瑞士军刀。我们重点解剖find,让你彻底掌握它的精髓。
一、locate:快但依赖索引
locate之所以快,是因为它不扫描磁盘,而是查询预先构建好的数据库(通常由系统定时任务自动更新)。你也可以手动运行updatedb刷新索引。
优点:秒出结果,适合模糊查找。
缺点:非实时,刚创建的文件可能找不到;只能按文件名匹配。
常用选项:
-b:只匹配路径中的基名(文件名部分)
-c:统计匹配数量
-r:支持基本正则表达式
示例:
locate -b '\passwd' # 查找所有名为 passwd 的文件locate -c '*.conf' # 统计有多少 .conf 文件
不过,locate功能有限,真正的重头戏是find。
二、find:实时、精准、强大
find通过遍历指定目录树来实时查找,虽然比locate慢一点,但胜在精确、灵活,支持各种条件组合。
基本用法
find [起始路径] [查找条件] [处理动作]
起始路径:默认当前目录
查找条件:按文件名、大小、类型、权限、时间等筛选
处理动作:默认打印,也可执行删除、复制等操作
1. 按文件名查找
-name "pattern":区分大小写,支持通配符(*, ?, [])
-iname "pattern":忽略大小写
-regex pattern:按正则匹配完整路径(很少用)
find /etc -name "*.conf"find /home -iname "readme*"
2. 按文件类型查找
-type后面跟类型标识:
f:普通文件
d:目录
l:符号链接
b:块设备
c:字符设备
p:管道
s:套接字
find /dev -type b # 找块设备find /var -type d -name "log" # 找名为 log 的目录
3. 按从属关系查找
-user username:属主
-group groupname:属组
-uid UID / -gid GID
-nouser:无属主(孤儿文件)
-nogroup:无属组
find / -nouser -o -nogroup # 找孤儿文件find /home -user alice # 找 alice 的文件
4. 按文件大小查找
-size [+|-]n[单位]
常用单位:c(字节)、k、M、G
n:匹配大小为 (n-1, n] 区间
-n:匹配 [0, n-1]
+n:匹配 (n, ∞)
find /var -size +100M # 大于100MBfind /etc -size -1k # 小于1KBfind . -size 1024c # 恰好1024字节
5. 按时间戳查找
Linux文件有三个时间:
atime:访问时间
mtime:修改时间(内容)
ctime:改变时间(属性或内容)
以“天”为单位:-atime, -mtime, -ctime
以“分钟”为单位:-amin, -mmin, -cmin
数值含义(以-atime为例):
find /tmp -atime +30 # 30天未访问的文件find /etc -mtime -7 # 最近7天修改过的文件find /var -cmin -60 # 最近1小时内属性改变的文件
6. 按权限查找
-perm [/|-]mode
-perm mode:精确匹配(权限完全等于mode)
-perm /mode:任意一类用户的任意一位匹配即满足(或关系),0表示忽略
-perm -mode:每类用户的每一位都必须满足(与关系)
find /bin -perm 755 # 权限正好是755find /etc -perm /222 # 任何人可写(任意用户有写权限)find /usr -perm -4000 # 设置了SUID(setuid位)
理解技巧:
/ 是“只要有就行”(或)
- 是“全部都要有”(与)
7. 组合条件:与、或、非
优先级:! > -a > -o,可用圆括号改变顺序(需转义或加引号)。
# 找出 /tmp 下属主非 root 且文件名不含 fstab 的文件find /tmp ! \( -user root -o -name "*fstab*" \) -ls
这里用到了德摩根定律:!A AND !B = !(A OR B),很实用。
三、处理动作:不只是看看
find找到文件后,可以对它们做点什么:
动作 | 说明 |
|---|
-print
| 默认,打印路径 |
-ls
| 类似 ls -l 详细列表 |
-delete
| 删除匹配的文件 |
-fls file
| 将长格式信息保存到文件 |
-ok command {} \;
| 执行命令,每次询问 |
-exec command {} \;
| 执行命令,不询问 |
{}代表当前找到的文件路径,\;表示命令结束(分号需转义)。
find /tmp -name "*.tmp" -delete # 删除临时文件find /var/log -name "*.log" -exec gzip {} \; # 压缩日志find /home -empty -ok rm {} \; # 删除空文件前确认
注意:-exec会将所有匹配结果一次性传递给命令,如果文件过多可能导致参数过长。可以用xargs分批处理:
find /var -type f -name "*.log" | xargs -n 10 gzip
xargs常用选项:
find . -name "*.jpg" | xargs -I {} cp {} /backup/find . -name "*.txt" | xargs -P 4 gzip # 4线程压缩
四、实战练习(附答案)
1 查找 /var 下属主为 root、属组为 mail 的文件或目录
find /var -user root -group mail
2 查找 /usr 下不属于 root、bin、hadoop 的文件或目录(两种方法)
find /usr ! \( -user root -o -user bin -o -user hadoop \)find /usr ! -user root ! -user bin ! -user hadoop
3 查找 /etc 下最近一周内容修改过,且属主不是 root 也不是 hadoop 的文件或目录
find /etc -mtime -7 ! \( -user root -o -user hadoop \)
4 查找系统上没有属主或属组,且最近一周内被访问过的文件或目录
find / \( -nouser -o -nogroup \) -atime -7
5 查找 /etc 下大于1M的普通文件
find /etc -size +1M -type f
6 查找 /etc 下所有用户都没有写权限的文件
find /etc -type f ! -perm /222
7 查找 /etc 下至少有一类用户没有执行权限的文件
find /etc -type f ! -perm -111
8 查找 /etc/init.d 下所有用户都有执行权限,且其他人有写权限的文件
find /etc/init.d -type f -perm -113
五、总结
掌握find就像拥有了一把文件系统的瑞士军刀。多练几次,你就能在茫茫文件海中精准定位目标。下次遇到“找不到文件”的情况,别再ls -R了,试试find吧!