951 字
5 分钟
日志排查利器:grep、sed、awk 文本处理实战

服务器上绝大多数信息都是纯文本:日志、配置、命令输出。grep、sed、awk 是处理这类文本的三件基础工具。本文不复述参数手册,而是用一条「排查 Nginx 访问日志」的主线把它们串起来。

示例日志格式(combined):

203.0.113.10 - - [02/Sep/2026:10:15:01 +0800] "GET /api/users HTTP/1.1" 200 1234 "-" "curl/8.0"

grep:先缩小范围#

排查的第一步永远是过滤。grep 模式 文件 把匹配行打印出来:

Terminal window
grep ' 500 ' /var/log/nginx/access.log # 找状态码 500 的行
grep -c ' 500 ' /var/log/nginx/access.log # 只统计行数
grep -v ' 200 ' access.log # 反向:排除正常请求
grep -i 'timeout' app.log # 忽略大小写
grep -r 'database' /etc/nginx/ # 递归搜目录

三个高频技巧:

  • grep -A 5 -B 2 'ERROR' app.log:同时显示匹配行后 5 行、前 2 行,看异常堆栈时必备。
  • grep -E '401|403' access.log:-E 启用扩展正则,多模式「或」匹配。
  • 想按词匹配(避免 error 匹配到 terror),加 -w。

awk:按列统计#

awk 默认按空白切分列,$1 是第一列。统计访问日志里各状态码的数量:

Terminal window
awk '{print $9}' access.log | sort | uniq -c | sort -rn

拆解这条管道:$9 取出状态码列 → sort 排序 → uniq -c 去重计数 → 按数量倒序。

awk 真正的威力在条件与计算:

Terminal window
# 只看 500 错误,打印时间和路径
awk '$9 == 500 {print $4, $7}' access.log
# 统计响应体总字节数($10 求和)
awk '{sum += $10} END {print sum/1024/1024 " MB"}' access.log
# 找出响应最大的 5 个请求
awk '{print $10, $7}' access.log | sort -rn | head -5

行筛选条件写在 {} 前面,多列处理写在里面,「先条件后动作」是 awk 的基本句式。

sed:批量改写#

sed 按行处理,最常用于替换和删行:

Terminal window
sed 's/404/找不到页面/' app.log # 每行只替换第一个匹配
sed 's/404/找不到页面/g' app.log # 加 g 全部替换
sed -n '100,200p' big.log # 只打印第 100~200 行
sed '/DEBUG/d' app.log # 删除含 DEBUG 的行

默认只把结果打印到屏幕,不改文件。确认无误后再加 -i 就地修改,macOS 下 -i 需要跟一个备份后缀参数(如 sed -i '.bak'),与 GNU sed 行为不同。

改配置文件前先备份是铁律:

Terminal window
cp nginx.conf nginx.conf.bak
sed -i 's/listen 80;/listen 8080;/' nginx.conf

组合拳:定位「哪个 IP 在刷接口」#

线上接口告警,怀疑被恶意爬取。三步定位:

Terminal window
# 1. 近一小时的日志里,按 IP 统计请求数
grep '02/Sep/2026:10' access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head
# 2. 看看第一名 IP 都在访问什么路径
grep '^203.0.113.10 ' access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head
# 3. 确认它的 User-Agent
grep '^203.0.113.10 ' access.log | awk -F'"' '{print $6}' | sort -u

第 3 步用了 -F'"' 以双引号切分,因为 User-Agent 里含空格,按空格切会错位。日志分析里「选对分隔符」比记更多参数更重要。

正则避坑#

  • . 在正则里匹配任意字符,想匹配字面句点要写 \.(比如匹配 IP)。
  • * 表示「前一个字符重复零次或多次」,不是 shell 通配符里的「任意串」;任意串是 .*。
  • grep 默认是基础正则(BRE),+、?、| 需要 -E 或转义。
  • 拿不准正则时,先用小样本验证:grep -E '你的模式' sample.log | head。

什么时候该换工具#

三剑客适合几十 MB 到几 GB 的单机文本。如果日志已经集中收集到 ELK/Loki,或者要做复杂的关联分析,就该用平台查询而不是在服务器上敲管道了——工具的价值在于「就地、快速、零依赖」。

延伸阅读#

日志排查利器:grep、sed、awk 文本处理实战
https://meow.us.kg/posts/linux-text-processing-grep-sed-awk/
作者
もゆちゃん
发布于
2026-09-02
许可协议
CC BY-NC-SA 4.0

分享文章

生成精美分享图或复制链接,与更多人分享本文。

继续阅读

沿着主题读

基于共同的标签与分类

换条路线

从其他文章中稳定抽取