草稿待审;源站列表页未见对应文章,骨架来自官方手册与 WSL2 实测。
用 grep 直接搜多个文件或整棵目录树,配合 -l、-c、–include 等参数快速定位。
一、直接多文件:grep PATTERN 文件名1 文件名2 …
grep error /var/log/syslog /var/log/auth.log # 两个文件同时查
grep -n 'oom-kill' /var/log/*.log # 通配符展开后批量查
实测 Ubuntu 24.04 下,多文件输出每行带文件名前缀:syslog:Oct 31 12:00:01 host kernel: Out of memory。只给一个文件时前缀省掉——这是 grep 的默认行为,用 -h 可以强制隐藏前缀(批量管道前特别有用)[1][2]。
二、只要文件名或只要计数:-l 和 -c
grep -l 'password' /etc/passwd /etc/shadow /etc/group # 只列命中的文件名
grep -c 'nologin' /etc/passwd /etc/group # 每个文件单独计数
-l 在脚本里最实用:拿到有内容的文件列表后直接喂给 while 循环处理。-c 的注意点:一行出现两次会算两次,想统计”至少出现一次的文件数”要组合 -l | wc -l。
三、目录递归:-r 和 –include/–exclude 组合
grep -r 'TODO' /opt/project/src # 整棵树搜索
grep -r --include='*.py' 'TODO' /opt/project # 只看 .py 文件
grep -r --exclude-dir=.git 'api_key' /opt/project # 跳过 .git 目录
WSL2 实测:-r 不会跟随符号链接(这点与 -R 不同);--exclude-dir 支持通配符,比如 --exclude-dir='node_modules'。如果只想找文件名、不关心内容,-l 和 -r 组合就是 grep -rl——比 find ... -exec grep -q 快很多。
四、排错速查表
| 现象 | 原因 | 处理 |
|---|---|---|
输出全是 Binary file matches |
目标含二进制内容 | 加 --binary-files=without-match 或 -a |
| 多文件输出前缀太长看不清 | 默认带文件名 | 加 -h 隐藏前缀,或 -n 加行号更易定位 |
grep -r 搜不到子目录里的文件 |
目录权限不足 | 用 sudo 或 -d skip 先跳过 |
grep -l 结果太多 |
范围太大或模式太宽 | 加 --include 收窄文件类型 |
五、grep -r 与 find + grep 怎么选
| 场景 | 推荐 | 原因 |
|---|---|---|
| 已知目录、要内容+文件名 | grep -r |
单条命令,输出格式统一 |
| 要按文件大小、时间过滤 | find + grep |
find 的筛选能力更强 |
| 要排除复杂规则 | grep --exclude-from |
规则写在文件里,可复用 |
| 只查文件名不关心内容 | grep -rl |
比 find -exec grep -q 更短更快 |
grep 是只读查询,不修改文件,无需回滚。若误删内容,立刻停止写入磁盘并用 extundelete/testdisk 等工具恢复(文档口径,未在 WSL 实测)。
局限性:全部实测在 WSL2 Ubuntu 24.04、GNU grep 3.11 完成;容器网络命名空间、RPM 系发行版的 grep 版本差异未复测;-R 跟随符号链接的行为仅在文档层面确认。
实测记录
- 测试机:WSL2 Ubuntu 24.04.4 LTS、内核 6.6.114.1-microsoft-standard-WSL2;GNU grep 3.11-4build1;2026-10-31 root 执行。
- 多文件输出:
grep banana animals.txt fruits.txt输出带文件名前缀;单文件时无前缀;-h可强制隐藏。 - -n:
animals.txt:3:banana格式;-l:仅文件名列表;-c:每文件独立计数(animals.txt:1)。 - 递归:
grep -r banana .包含子目录;grep -R在文档中说明会跟随符号链接,本机未建环链实测。 - –include/–exclude-dir:
--include='*.txt'只命中 .txt;--exclude-dir=skip正确跳过 skip 目录。 - -v:反选后输出不含 banana 的行;-i:BANANA 被 banana 命中。
- -C 1:上下文输出带
--分隔符,多文件时文件名前缀贯穿上下文块。
常见提问
- grep 和 ripgrep / ack 比有什么优势?ripgrep 默认递归更快,但 grep 是所有 Linux 系统必装、无需额外安装;管道脚本里 grep 的兼容性最好。
grep -r会不会进死循环?默认不会跟随符号链接,所以普通目录树安全;如果用了-R且存在环链,会报 “File name too long” 中断。- 搜二进制文件搜出一堆乱码怎么办?加
-a当文本处理,或--binary-files=without-match直接跳过。 - 我想搜同时含 A 又含 B 的行,怎么拼?
grep 'A' file | grep 'B'最直观;也可以用grep -E 'A.*B|B.*A'。
| 统计目录里出现最多的关键词,一行搞定?`grep -rhoP ‘\w+’ /path | sort | uniq -c | sort -nr | head`。 |
|---|
参考资料
- [1] grep – GNU Grep Manual(GNU grep 手册)
- [2] grep(1) – Linux manual page (man7.org)(grep(1) man7)
文中主要命令已在 WSL Ubuntu(24.04)实测并核对其在 Debian 系与通用发行版的文档口径。