Linux 文本处理三剑客 grep、sed、awk 的五个实用用法
Linux 文本处理三剑客 grep、sed、awk 的五个实用用法
在 Linux 日常运维与数据分析中,grep、sed 和 awk 被合称为"文本处理三剑客"。它们各有所长:grep 擅长按模式检索,sed 擅长原地流式替换,awk 擅长按列计算。下面整理五个高频实用用法,附带可直接复制运行的短代码示例。
一、用 grep 递归查找含关键字的文件及所在行
排查日志时,常常需要在整个目录下搜索包含特定关键字的文件。grep -rn 是最常用的组合:-r 递归遍历目录,-n 显示行号,加上 --include 可以限定文件类型。
# 在当前目录及子目录的 .log 文件中搜索 "ERROR",显示文件名与行号
grep -rn --include="*.log" "ERROR" ./logs/
# 忽略大小写搜索
grep -rni --include="*.conf" "timeout" ./etc/
如果只想看命中了关键字的文件名,不用具体内容,加 -l 即可(--files-with-matches):
grep -rl "TODO" ./src/
二、用 sed 在日志中批量替换并原地保存
sed 是"流编辑器",配合 -i 可在文件内直接修改,不用先 cp 再覆盖。下面的例子演示两个常见场景:打敏信息和改主机名。
# 把所有明文 IP 10.0.0.5 替换为 <IP_REDACTED>,直接修改原文件
sed -i 's/10\.0\.0\.5/<IP_REDACTED>/g' app.log
# 只查看替换效果,不改原文件(推荐先预览)
sed 's/10\.0\.0\.5/<IP_REDACTED>/g' app.log | head
批量处理多个文件时,可以把 -i 和通配符合用,但务必先备份:
cp -r conf/ conf.bak
sed -i 's/old-host/new-host/g' conf/*.yml
三、用 awk 按列求和与统计
awk 默认按空白分隔字段,$1、$2 依次表示各列。统计 Nginx 访问日志的 4xx/5xx 比例是一个典型用法。
# access.log 格式: IP - - [date] "METHOD /path" STATUS SIZE
# 统计各状态码出现的次数
awk '{print $9}' access.log | sort | uniq -c | sort -rn
如果文件已经是"数字 名称"的简单格式,可以直接用 awk 做求和与平均值:
# 文件每行: CPU_percent 进程名,求第一列的均值
awk '{sum+=$1; n++} END {printf "均值 %.2f,共 %d 行\n", sum/n, n}' cpu_usage.txt
利用 BEGIN/END 还能在首尾打印表头表尾,适合生成简易报表。
四、三剑客组合:管道串接 grep | awk | sed
实际场景中最有威力的是把它们用管道拼在一起。例如从系统 journal 中挑出某服务的 ERROR 行,再提取时间戳与消息,并把双引号替换为单引号方便后续入库:
journalctl -u myservice 2>/dev/null \
| grep "ERROR" \
| awk '{print $1, $2, $3, $NF}' \
| sed 's/"/'"'"'/g'
另一条常用组合是从 nginx 日志中取出访问超过 2 秒的慢请求,并只保留 IP 和 URL:
awk '$NF > 2.0' access.log | awk '{print $1, $7}' | sort | uniq -c | sort -rn | head -20
五、用 grep -c 与 awk 做轻量健康检查脚本
把 grep 和 awk 放进一个 shell 小脚本,就能做成服务健康巡检。下面的脚本每分钟从日志尾检查一次,连续三次命中就告警:
#!/bin/bash
THRESH=3
COUNT=0
tail -F /var/log/myapp.log | while read -r line; do
if echo "$line" | grep -q "OutOfMemoryError"; then
COUNT=$((COUNT + 1))
if [ "$COUNT" -ge "$THRESH" ]; then
echo "[$(date)] 连续 $COUNT 次 OOM,发送告警"
# 此处可接 curl 调用告警 webhook
break
fi
else
COUNT=0
fi
done
用 grep -c 也能一行搞定期末统计:
# 统计每个用户出现的行数
awk -F: '{print $1}' /etc/passwd | sort | uniq -c
# 或用 grep -c 快速查看某文件中匹配的行数
grep -c "WARN" /var/log/myapp.log
小结
- grep 管"找",sed 管"换",awk 管"算"。
- 先 grep 过滤,再 awk 取列,最后 sed 清洗,是 Linux 文本处理最顺手的心法。
- 对 sed -i 和覆盖写入保持谨慎,改前备份,改前先在不带 -i 的管道中预览结果。
- 点赞
- 收藏
- 关注作者
评论(0)