一、最常用的六个参数
grep "error" app.log # 基本匹配
grep -i "error" app.log # 忽略大小写
grep -n "error" app.log # 显示行号
grep -c "error" app.log # 只输出匹配行数
grep -v "DEBUG" app.log # 反选:不包含的行
grep -r "TODO" ./src # 递归搜索目录
-r 是排查代码最常用的:在项目根目录执行 grep -rn "函数名" .,能直接定位定义位置。
二、看上下文:-A / -B / -C
日志里一条错误往往要配前后几行才有意义:
grep -A 5 "Exception" app.log # 匹配行 + 后 5 行
grep -B 3 "Exception" app.log # 匹配行 + 前 3 行
grep -C 5 "Exception" app.log # 前后各 5 行
排查堆栈时 -A 20 基本能把整段异常打完。
三、限定文件类型与排除目录
grep -rn --include="*.py" "def main" .
grep -rn --exclude-dir=node_modules --exclude-dir=.git "api_key" .
不加 --exclude-dir 时,在前后端混合项目里搜一个常见词会刷出几万行来自 node_modules 的结果,实际有效信息为零。
四、正则:-E 与 -F
grep -E "error|warn|fatal" app.log # 扩展正则,支持 |
grep -F "a.b.c" file # 固定字符串,不当正则解析
grep -P "\d{11}" file # Perl 正则(GNU grep 支持)
要点:
- 默认是基础正则,
|+?需要转义;-E后可以直接写。 - 搜含
.*[的字面量(如版本号1.2.3)时用-F,避免被当正则。 -P不是所有平台都支持(macOS 自带 grep 就没有),跨平台脚本里避免依赖。
五、排查日志的经典组合
# 某时间段的错误,带上下文
grep "2026-11-03 10:" app.log | grep -i error -A 3
# 统计接口耗时超过 1 秒的请求数
grep -c "cost=[1-9][0-9]\{3,\}ms" access.log
# 排除健康检查的噪音
grep -v "/health" access.log | grep " 500 "
# 找某个 IP 的请求
grep -F "1.2.3.4" access.log | tail -50
再配合 awk 提取字段、sort | uniq -c | sort -rn 做 TopN 统计,基本能覆盖大部分线上排查。
六、几个坑
grep遇到二进制文件会输出Binary file xxx matches,加-a当文本处理,或-I跳过二进制。- 颜色:
--color=auto让匹配高亮,长输出时更容易定位。 - 大文件:
grep是流式的,几 GB 日志也能扫,但注意别用-r扫整个根目录。 - 中文:
grep按字节匹配,理论上可能切到半个汉字,实际很少出问题;-i对中文无效(没有大小写概念)。 - 行尾符:Windows 文件带
\r,grep "abc$"可能匹配不到,用dos2unix先转换。
七、和 find 的分工
find 按文件属性找(名字、时间、大小),grep 按内容找。组合起来就是「在符合条件的文件里搜内容」:
find . -name "*.log" -mtime -1 -exec grep -l "Timeout" {} \;
小结
-r 递归、-n 行号、-i 忽略大小写、-v 反选、-C 上下文;限定类型用 --include,排除用 --exclude-dir;搜字面量用 -F,搜多关键词用 -E。