grep是搜索文件内容的工具,常用-n显示行号、-r递归目录、-i忽略大小写、--include/--exclude-dir限定范围,需避免误当find用、未转义特殊字符及未控制文件类型导致性能问题。

grep 不是查文件名的工具,它是查**文件内容**的。想快速定位某段文字在哪一行、哪个文件里,直接用 grep 配合合适选项,比先 find 再 cat 再人工扫更可靠。
搜索单个关键词并显示行号
最常用场景:你知道要找什么词,想立刻看到它在哪几行出现。
用 grep -n 最稳妥,-n 保证每行输出带行号,避免漏看上下文。
-
grep -n "error" /var/log/syslog—— 查日志里所有含error的行,带编号 - 加
-i忽略大小写:grep -ni "warning" app.log - 如果文件路径含空格,必须用引号包裹:
grep -n "timeout" "my config.txt" - 不加
-n时,grep默认只输出匹配行本身,容易在长输出里丢失位置感
同时匹配多个关键词(AND 逻辑)
grep 本身不支持 AND 语法,但可以用管道串联实现“必须同时出现”。
-
grep "user" access.log | grep "404"—— 先筛出含user的行,再从结果里找含404的 - 注意顺序:把更稀有的词放前面,减少中间数据量,比如
grep "500" | grep "POST"比反过来快 - 不能写成
grep "user AND 404"—— 这会被当成字面字符串去搜,不是逻辑运算 - 若需正则表达式级的“同一行含两个词”,得用
-E和分组,例如:grep -E "user.*404|404.*user" access.log
递归搜索整个目录下的所有文本文件
想在整个项目目录里搜某个配置项或函数名,别一个个进子目录。
-
grep -r "DATABASE_URL" ./src——-r自动进入子目录,但默认会搜二进制文件,可能报错或卡住 - 加
--include="*.py"限定后缀:grep -r --include="*.py" "def main" . - 加
--exclude-dir=node_modules跳过干扰目录:grep -r --exclude-dir=node_modules "fetch(" . - 遇到
Binary file xxx matches提示,说明碰到了二进制文件;加-I(大写 i)可跳过所有二进制文件,比--text更干脆
避免常见误用和性能陷阱
很多人用 grep 卡住或结果不准,往往栽在这几个点上。
- 把
grep当find用:比如grep "config.yml" *是在当前目录所有文件里搜字符串config.yml,不是找叫config.yml的文件 —— 找文件名请用find -name - 没转义特殊字符:搜索
$PATH或foo[bar]时,方括号、美元符会被当正则元字符处理,应写成grep '\$PATH' script.sh或用grep -F(固定字符串模式) -
grep -r在大目录下很慢,尤其没加--include时,默认遍历所有文件类型;生产环境建议先find . -name "*.log" -exec grep -l "panic" {} +控制范围 -
grep返回值是关键:脚本里判断是否找到,应该检查$?,而不是看输出是否为空;grep -q可静默执行,专为判断设计
grep 的威力不在花哨参数,而在精准控制“搜什么、在哪搜、怎么停”。真正卡住人的,往往是没意识到它默认按行处理、不递归、不区分文件类型——这些隐含行为,比语法本身更容易导致结果偏差。










