第3章:文本处理三剑客(上):grep命令详解
说实话,在运维和开发这条路上摸爬滚打这么多年,我越来越觉得grep就是那个「平时不起眼,关键时刻救命」的工具。你想想看,每天面对成百上千行日志,眼睛都快看花了,这时候grep就是你的第二双眼睛。
我个人习惯是,不管排查什么问题,第一反应就是grep。不是因为它多高级,而是因为它够快、够准。今天咱们就好好聊聊这个老朋友。
3.1 正则表达式基础
先别急着敲命令。grep的核心能力,说白了就是「模式匹配」。而这个「模式」,就是正则表达式。
正则表达式是什么?我打个比方:它就像一套暗号系统。你告诉grep「帮我找所有以ERROR开头的行」,grep就乖乖去翻日志。这套暗号,就是正则。
3.1.1 基本元字符
| 元字符 | 含义 | 示例 |
|---|---|---|
. |
匹配任意单个字符 | a.c 匹配 abc、adc |
* |
匹配前一个字符0次或多次 | ab*c 匹配 ac、abc、abbc |
^ |
匹配行首 | ^Error 匹配以Error开头的行 |
$ |
匹配行尾 | failed$ 匹配以failed结尾的行 |
[] |
匹配括号内任意一个字符 | [0-9] 匹配任意数字 |
[^] |
匹配不在括号内的字符 | [^0-9] 匹配非数字 |
嗯,这里要注意:^ 在方括号里外含义完全不同。我在项目中遇到过好几次新人搞混这个,排查半天找不到原因。
3.1.2 扩展正则
基本正则够用,但有时候你会觉得它「不够聪明」。比如你想匹配「abc」或「def」,基本正则写起来很别扭。这时候就需要扩展正则了。
# 基本正则:用 \| 表示或
grep 'abc\|def' log.txt
# 扩展正则:用 | 表示或(更直观)
grep -E 'abc|def' log.txt
我个人强烈建议:直接用 grep -E 或者 egrep。少打几个反斜杠,代码也更好读。
3.2 grep常用选项详解
好了,正则基础有了,咱们来看看grep那些「救命」的选项。每个选项背后,都有我踩过的坑。
3.2.1 -i:忽略大小写
这个选项太常用了。日志里「Error」和「error」都可能出现,你总不能写两个正则吧?
# 不忽略大小写
grep 'error' app.log
# 只匹配小写error
# 忽略大小写
grep -i 'error' app.log
# 匹配 Error、ERROR、error 等
我曾经排查过一个线上问题,日志里写的是「ERROR」,我愣是grep了「error」半天没结果。后来加了 -i 才找到。嗯,从那以后我养成了习惯:不确定大小写时,先加 -i。
3.2.2 -v:反向匹配
这个选项很有意思。它不是找「匹配的」,而是找「不匹配的」。
# 查看所有非注释行
grep -v '^#' config.conf
# 排除包含 "DEBUG" 的行
grep -v 'DEBUG' app.log
你想想看,有时候日志里90%都是INFO,你只想看ERROR。这时候 -v 就派上用场了。我经常用它来「过滤掉噪音」。
grep -v 'healthcheck' /var/log/nginx/error.log
3.2.3 -c:计数
有时候你不需要看具体内容,只想知道「有多少行匹配」。
# 统计错误次数
grep -c 'ERROR' app.log
# 输出:42
# 统计非空行数
grep -c -v '^$' app.log
我记得有一次监控告警说「错误率飙升」,我第一反应就是 grep -c 'ERROR' 看看具体数量。配合时间范围,很快定位到问题。
3.2.4 -n:显示行号
这个选项,说白了就是「定位神器」。你找到问题了,但不知道在哪一行,怎么修?
# 显示匹配行及其行号
grep -n 'NullPointerException' app.log
# 输出:187: java.lang.NullPointerException at ...
配合编辑器,直接跳到187行。效率翻倍。
3.2.5 组合使用
这些选项单独用已经很香了,组合起来更是无敌。
# 统计非注释行数(忽略大小写)
grep -c -i -v '^#' config.conf
# 显示所有警告和错误(忽略大小写,显示行号)
grep -in 'error\|warn' app.log
我个人最常用的组合是 -in。为什么?因为日志里大小写不统一,行号又必须看。这两个一组合,基本覆盖了80%的场景。
3.3 知识体系总览
说了这么多,咱们用一张图来总结一下grep的核心逻辑。我画了个SVG,方便你理解。
3.4 避坑指南
最后,分享几个我踩过的坑,希望能帮你少走弯路。
- 忘记转义特殊字符: 比如你想匹配一个点号
.,直接写grep '.'会匹配所有字符。要用grep '\.'。 - 大文件不加限制: 几GB的日志直接grep,机器可能会卡死。建议先用
head或tail切分,或者用grep -m 100限制匹配行数。 - 忽略二进制文件: 有时候grep会匹配到二进制文件,输出一堆乱码。加
-I选项忽略二进制文件。
好了,grep的基础就聊到这儿。说白了,它就是一把「瑞士军刀」,简单但强大。多用、多练,你会发现它比你想象的更顺手。
可可精品资料库