4、文本处理三剑客:grep高级用法、sed流编辑器、awk文本分析工具
日志分析说白了就是跟文本打交道。你拿到手的可能是几GB的纯文本,也可能是结构化的JSON日志。这时候,grep、sed、awk这三个工具就是你的贴身武器。我做了这么多年运维和日志分析,可以负责任地告诉你——这三个家伙搞定了,日志分析你就入门了八成。
今天咱们一个一个来。不搞花架子,直接上干货。
4.1 grep高级用法:不只是搜索
很多人用grep,就知道一个grep "error" app.log。嗯,这确实能用,但效率太低了。我刚开始做日志分析时也这样,直到有一次线上故障,日志文件2个G,我硬是等了五分钟才搜完……后来才发现,加几个参数就能快几十倍。
4.1.1 常用参数速查
| 参数 | 作用 | 举个栗子 |
|---|---|---|
-i |
忽略大小写 | grep -i "error" app.log |
-v |
反向匹配(排除) | grep -v "DEBUG" app.log |
-c |
只统计匹配行数 | grep -c "500" access.log |
-n |
显示行号 | grep -n "NullPointer" app.log |
-r |
递归搜索目录 | grep -r "timeout" /var/log/ |
-A 3 |
匹配行后显示3行 | grep -A 3 "Exception" app.log |
-B 2 |
匹配行前显示2行 | grep -B 2 "FATAL" app.log |
-C 2 |
匹配行前后各显示2行 | grep -C 2 "OOM" app.log |
-E |
启用扩展正则 | grep -E "error|fatal|critical" app.log |
-C 5。只看错误行往往不够,上下文才是破案的关键。有一次数据库连接池爆了,光看"Connection refused"看不出啥,但加上前后5行,立马发现是某个接口没释放连接。
4.1.2 正则表达式实战
grep配合正则,才是真正的杀手锏。你想想看,日志里IP地址、时间戳、UUID这些固定格式的东西,用正则一把抓,多爽。
# 匹配所有IP地址
grep -E "\b([0-9]{1,3}\.){3}[0-9]{1,3}\b" access.log
# 匹配时间戳格式 2024-01-15 14:30:00
grep -E "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}" app.log
# 匹配HTTP状态码(4xx或5xx)
grep -E "\" [45][0-9]{2} " access.log
# 匹配UUID格式
grep -E "[a-f0-9]{8}-([a-f0-9]{4}-){3}[a-f0-9]{12}" app.log
grep -E "[0-9]*" 想匹配数字,结果把整份日志全打出来了。为什么?因为 * 匹配零次或多次,空字符串也算!记住:[0-9]* 会匹配所有行,应该用 [0-9]+。
4.2 sed流编辑器:文本的瑞士军刀
sed的全称是Stream Editor,流编辑器。它不把文件加载到内存,而是一行一行地处理。这就意味着——处理大文件时,sed几乎不占内存。我处理过10GB的日志文件,sed跑起来依然稳如老狗。
4.2.1 核心操作:增删改查
| 操作 | 命令格式 | 说明 |
|---|---|---|
| 替换 | sed 's/旧/新/g' |
全局替换,不加g只替换每行第一个 |
| 删除 | sed '/模式/d' |
删除匹配模式的行 |
| 打印 | sed -n '/模式/p' |
只打印匹配的行(-n取消默认输出) |
| 插入 | sed '3i\内容' |
在第3行前插入 |
| 追加 | sed '3a\内容' |
在第3行后追加 |
4.2.2 实战场景:日志脱敏与格式化
日志分析中,经常需要脱敏。比如把手机号、身份证号替换掉。我有个项目需要把日志里的密码字段全部抹掉,用sed一行搞定。
# 脱敏:把手机号中间四位变成****
sed -E 's/(1[3-9][0-9])[0-9]{4}([0-9]{4})/\1****\2/g' app.log
# 脱敏:把password=后面的值替换为***
sed -E 's/password=[^& ]+/password=***/g' app.log
# 只打印第100到200行
sed -n '100,200p' huge.log
# 删除所有空行
sed '/^$/d' app.log
# 在每行开头加上行号
sed = app.log | sed 'N;s/\n/ /'
重点:sed默认不会修改原文件。想直接改文件,加 -i 参数。但建议先不加 -i 跑一遍看看效果,确认无误再加。我曾经手滑 sed -i 's/production/development/g' config.yml,差点把线上配置改了……
4.3 awk文本分析工具:列处理之王
awk跟grep和sed最大的区别是什么?grep是行匹配,sed是行编辑,而awk是列处理。日志文件很多都是结构化文本——空格分隔、逗号分隔、竖线分隔。awk就是为这种场景而生的。
我记得第一次用awk分析Nginx日志,想统计每个IP的访问次数。用Python写了个脚本,跑了半天。后来同事说:你试试awk。一行命令,3秒出结果。从那以后,我就彻底服了。
4.3.1 基本结构
awk '模式 { 动作 }' 文件名
awk逐行读取文件,如果匹配模式,就执行动作。模式可以省略(匹配所有行),动作也可以省略(默认打印整行)。
| 内置变量 | 含义 |
|---|---|
$0 |
整行内容 |
$1, $2, ... |
第1列、第2列…… |
NF |
当前行的列数 |
NR |
当前行号 |
FS |
列分隔符(默认空格/制表符) |
OFS |
输出列分隔符(默认空格) |
4.3.2 实战:Nginx日志分析
假设你的access.log格式是这样的:
192.168.1.1 - - [15/Jan/2024:14:30:00 +0800] "GET /api/users HTTP/1.1" 200 1234
# 统计每个IP的访问次数
awk '{ count[$1]++ } END { for (ip in count) print ip, count[ip] }' access.log
# 统计每个URL的访问次数($7是URL)
awk '{ count[$7]++ } END { for (url in count) print url, count[url] }' access.log
# 找出所有返回500的行
awk '$9 == 500 { print }' access.log
# 计算所有成功请求的响应体大小总和
awk '$9 == 200 { sum += $10 } END { print "Total:", sum, "bytes" }' access.log
# 按列分隔符":"处理/etc/passwd
awk -F: '{ print $1, "的家目录是", $6 }' /etc/passwd
我的经验:awk的数组非常强大。上面统计IP的例子,count[$1]++ 就是在用IP做key,每次出现就加1。最后在END块里遍历输出。这种模式在日志分析中太常用了——分组统计、去重、Top N,全都能搞定。
4.4 三剑客合璧:一个完整的日志分析流程
单独用每个工具都能干活,但把它们组合起来,才是真正的降维打击。我给你看一个我实际用过的例子。
场景:分析Nginx访问日志,找出今天访问量最大的10个IP,以及它们各自访问最多的URL。
# 第一步:用grep过滤出今天的日志
grep "15/Jan/2024" access.log > today.log
# 第二步:用awk统计IP访问次数,排序取Top 10
awk '{ count[$1]++ } END { for (ip in count) print count[ip], ip }' today.log | sort -rn | head -10 > top_ip.txt
# 第三步:对每个Top IP,用awk统计其访问的URL
while read line; do
ip=$(echo $line | awk '{print $2}')
echo "=== $ip ==="
grep "$ip" today.log | awk '{ url[$7]++ } END { for (u in url) print url[u], u }' | sort -rn | head -5
done < top_ip.txt
你看,grep负责过滤,awk负责统计,sort和head负责排序截取。每个工具做自己最擅长的事,组合起来就是一条完整的数据管道。
核心思想:日志分析的本质就是过滤 → 提取 → 统计 → 输出。grep做过滤,awk做提取和统计,sed做格式化输出。记住这个流程,任何日志你都能分析。
4.5 知识体系总览
下面这张图,把三剑客的核心能力和关系梳理清楚了。建议你保存下来,以后用的时候对照着看。
4.6 本章小结
- grep:核心是搜索过滤。记住
-E扩展正则、-C上下文、-v排除,这三个最常用。 - sed:核心是流式编辑。记住
s/旧/新/g替换、/模式/d删除、-n配合p打印。 - awk:核心是列处理。记住
$1取列、count[$1]++统计、END块输出结果。 - 组合:grep过滤 → awk统计 → sed格式化,这是日志分析的黄金流程。
最后说一句:这三个工具不要死记硬背。你只需要记住它们能干什么,具体语法忘了就查。用得多了,自然就记住了。我到现在还经常查sed的替换语法呢——这不丢人,效率才是王道。