grep是用于在文件中搜索匹配行的命令,支持忽略大小写(-i)、整词匹配(-w)、上下文显示(-a/-b/-c)及行缓冲(--line-buffered)等关键功能,避免uuoc。

直接用 grep 读文件,别套 cat
绝大多数情况下,grep "keyword" /path/to/log 就够了。新手常写 cat /path/to/log | grep "keyword",这叫 UUOC(Useless Use of Cat),多启一个进程、多一次 I/O,纯属拖慢速度。只有当前命令本身不读文件(比如 tail、journalctl、dmesg)时,才需要管道交给 grep。
匹配不全?先确认大小写和边界
日志里 “Error”、“ERROR”、“error” 混着写是常态,不加 -i 很容易漏掉关键行;而搜 “user” 却把 “username”、“debug_user” 全捞出来,是因为没限制单词边界。实际排查时建议:
- 统一忽略大小写:
grep -i "error" app.log - 精准匹配完整单词:
grep -w "timeout" system.log(-w确保前后是单词分隔符) - 更严格匹配开头/结尾:
grep "\<panic>" kern.log</panic>(\ 和 <code>\>是 GNU grep 支持的单词锚点)
只看关键词附近几行?用 -A、-B、-C
单看一行经常无法判断上下文——比如报错前有没有请求 ID,错误后有没有堆栈。这时不能靠肉眼翻页,得让 grep 自带上下文输出:
-
grep -A 3 "OOM killed" dmesg.log:显示匹配行 + 后 3 行 -
grep -B 2 "connection refused" network.log:显示匹配行 + 前 2 行 -
grep -C 5 "exception" app.log:显示匹配行 ± 5 行(共 11 行)
注意:-C 输出默认不带行号,加 -n 才能定位原始位置,比如 grep -C 2 -n "segfault" core.log。
实时监控日志时,--line-buffered 不是可选项
用 tail -f | grep 监控时,如果没加 --line-buffered,高并发日志下会卡住几秒甚至十几秒才刷出结果——因为 grep 默认按块缓冲,等攒够 4KB 才输出。这不是 bug,是默认行为。线上排查必须加:
tail -f /var/log/app.log | grep --line-buffered -i "fatal"- 搭配
awk或cut做字段提取时,也要确保前面所有命令都行缓冲,否则整条流水线都会延迟
真正容易被忽略的是:当管道链变长(比如 tail -f | grep | awk | head),中间任意一环没做行缓冲,就可能丢掉最新几条日志。调试时先单独跑 tail -f 看原始流是否实时,再逐段加过滤验证。











