文本处理三剑客 — grep、sed、awk 实战精讲

📖 知识点简介

日志分析、配置修改、数据提取是运维的日常三件套。grepsedawk 被誉为 Linux 文本处理"三剑客",是运维工程师必须掌握的利器:

  • grep --- 文本搜索过滤,快如闪电
  • sed --- 流式编辑替换,批量改配置利器
  • awk --- 结构化数据提取,列操作王者

三者配合使用,能解决 90% 的日常文本处理需求。今天用实战场景逐个击破。


🛠 核心命令整理

1️⃣ grep --- 文本搜索过滤器

bash 复制代码
# 基础搜索
grep "error" app.log                    # 搜索含 error 的行
grep -i "error" app.log                 # 忽略大小写
grep -v "debug" app.log                 # 排除含 debug 的行
grep -n "error" app.log                 # 显示行号

# 进阶用法
grep -c "error" app.log                 # 统计匹配行数
grep -r "timeout" /var/log/             # 递归搜索目录
grep -l "500" /var/log/nginx/*.log      # 只显示文件名
grep -A 3 -B 2 "OOM" syslog            # 显示匹配行前后文(A后B前)
grep -E "error|fatal|critical" app.log  # 扩展正则,多关键字匹配
grep -P "\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}" access.log  # Perl正则匹配IP

2️⃣ sed --- 流式编辑器

bash 复制代码
# 替换操作(核心场景)
sed 's/old/new/' file                   # 每行第一个 old 替换为 new
sed 's/old/new/g' file                  # 全局替换(g 标记)
sed 's/old/new/gi' file                 # 全局替换 + 忽略大小写
sed -i 's/old/new/g' file               # -i 直接修改文件(慎用!)
sed -i.bak 's/old/new/g' file           # 备份原文件后替换

# 行操作
sed -n '10,20p' file                    # 打印 10-20 行
sed '5d' file                           # 删除第 5 行
sed '/^#/d' config.conf                 # 删除注释行
sed '/^$/d' file                        # 删除空行
sed '3a\newline' file                   # 在第 3 行后追加

# 实战场景
sed -i 's/Listen 80/Listen 8080/' /etc/httpd/conf/httpd.conf  # 改端口
sed -i '/^MaxClients/c\MaxClients 500' /etc/httpd/conf/httpd.conf  # 修改配置行

3️⃣ awk --- 列处理与报表生成

bash 复制代码
# 基础字段提取
awk '{print $1}' file                   # 打印第一列
awk '{print $1, $NF}' file              # 第一列和最后一列
awk -F: '{print $1, $3}' /etc/passwd    # 指定分隔符(:)

# 条件过滤
awk '$3 > 100 {print $1, $3}' stats.txt # 第三列大于 100
awk '/error/ {print $0}' app.log        # 匹配 error 的行整行输出
awk 'NR==5' file                        # 打印第 5 行
awk 'NR>=10 && NR<=20' file             # 打印 10-20 行

# 内置变量与格式化
awk '{sum+=$1} END {print "总和:", sum}' data.txt      # 求和
awk '{sum+=$1; count++} END {print "平均:", sum/count}' # 求平均
awk '{printf "%-20s %8d\n", $1, $2}' file               # 格式化输出

# 数组与去重
awk '!seen[$0]++' file                  # 去除重复行
awk '{count[$1]++} END {for(ip in count) print ip, count[ip]}' access.log  # IP 计数

🔧 实操示例:Nginx 日志分析实战

假设有一份 Nginx 访问日志 access.log,格式如下:

arduino 复制代码
192.168.1.1 - - [25/Jun/2026:10:15:30 +0800] "GET /api/users HTTP/1.1" 200 1234
10.0.0.5 - - [25/Jun/2026:10:15:31 +0800] "POST /api/login HTTP/1.1" 401 56
192.168.1.1 - - [25/Jun/2026:10:16:00 +0800] "GET /api/orders HTTP/1.1" 500 89

场景 1:统计各 IP 的访问次数

bash 复制代码
awk '{print $1}' access.log | sort | uniq -c | sort -rn

场景 2:找出所有 5xx 错误

bash 复制代码
awk '$9 ~ /^5[0-9]{2}/ {print $1, $7, $9}' access.log

场景 3:统计每个 API 的请求次数(去 URL 参数)

bash 复制代码
awk '{split($7, a, "?"); print a[1]}' access.log | sort | uniq -c | sort -rn

场景 4:提取特定时间范围的日志

bash 复制代码
sed -n '/25/Jun/2026:10:15/,/25/Jun/2026:10:30/p' access.log

场景 5:三剑客组合拳 --- 找最活跃的 IP 并提取其请求

bash 复制代码
# 找出请求最多的 IP
top_ip=$(awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -1 | awk '{print $2}')
echo "最活跃 IP: $top_ip"

# 提取该 IP 的所有 5xx 错误
grep "$top_ip" access.log | awk '$9 ~ /^5[0-9]{2}/'

⚠️ 常见坑点与注意事项

grep 篇

  • 正则差异grep 默认是基础正则(BRE),| + ? 等需要用 -E 启用扩展正则,或加反斜杠转义
  • 二进制文件grep 遇到二进制文件会输出 Binary file matches,加 -a 强制文本模式
  • 大文件搜索 :用 -m N 限制匹配行数,避免刷屏,如 grep -m 10 "error" huge.log

sed 篇

  • -i 一定要备份 :生产环境养成习惯 sed -i.bak 's///g' file,配置改错只需 mv file.bak file
  • 定界符选择 :如果路径含 /,换用 |# 做定界符:sed 's|/var/www|/srv/www|g' file
  • 多行模式 :sed 默认逐行处理,跨行匹配需要用 N(多行模式),复杂场景建议换 awk

awk 篇

  • 变量作用域awk$1$2 是字段变量,NRNF 是内置变量,自定义变量不需加 $
  • 分隔符踩坑 :默认分隔符是空白(空格/Tab),如果字段内有空格要用 -F 指定,如 -F '","' 处理 CSV
  • 浮点数比较 :awk 的数值比较用 > < ==,但字符串比较用 ~(匹配)或 ==(精确)
  • 性能注意 :awk 逐行处理大文件性能很好,但频繁用 system() 调用外部命令会急剧变慢

💡 一句话口诀

grep 搜索行,sed 改内容,awk 切字段 grep 快且准,sed 批量改,awk 算统计 三剑客配管道,运维效率翻一番 🚀

相关推荐
sarasuki1 小时前
JavaScript的对象、new的机制与原型包装类
javascript·后端
某鹏1 小时前
java伪共享问题的稳定解法
后端
fliter1 小时前
Rust 不是手动内存管理:它是声明式内存管理
后端
AI人工智能_电脑小能手1 小时前
【大白话说Java面试题 第125题】【并发篇】第25题:说说 Java 线程的中断机制
java·后端·面试
fliter1 小时前
Box 里到底装了什么:从 Go interface 到 Rust trait object
后端
Java内核笔记1 小时前
Spring Security 源码解析(六)无状态 JWT 实践:Session 共享与自定义过滤器
java·后端
乘云数字DATABUFF1 小时前
5分钟部署开源APM Databuff:OpenTelemetry全链路追踪入门实战
运维·后端
杨利杰YJlio1 小时前
OpenClaw / clawdbot 是什么?看懂 Agent 体系
前端·后端
SamDeepThinking2 小时前
一条UPDATE语句在MySQL 8.0中到底加了几把锁?
后端·mysql·程序员