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

📖 知识点简介

日志分析、配置修改、数据提取是运维的日常三件套。grep、sed、awk 被誉为 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 是字段变量,NR、NF 是内置变量,自定义变量不需加 $
  • 分隔符踩坑 :默认分隔符是空白(空格/Tab),如果字段内有空格要用 -F 指定,如 -F '","' 处理 CSV
  • 浮点数比较 :awk 的数值比较用 > < ==,但字符串比较用 ~(匹配)或 ==(精确)
  • 性能注意 :awk 逐行处理大文件性能很好,但频繁用 system() 调用外部命令会急剧变慢

💡 一句话口诀

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

相关推荐
Java爱好狂.27 分钟前
Java初学者如何一周速通SpringBoot!
java·spring boot·后端·spring·高并发·架构师·java面试
马良神笔2 小时前
2026 年Rag最近技术前沿总结
后端·python·django
程序猿DD2 小时前
同样10美元,OpenDesign和Command Code的DeepSeek V4.1 Flash额度到底有多少?
后端
高频因子挖掘机3 小时前
A股量化从日线升级到5分钟线:数据量增加后最先暴露哪些工程问题?
后端·github·api
高频因子挖掘机3 小时前
历史行情返回顺序变了,为什么按行号计算指标很危险?
后端·github·api
团子哒哒5 小时前
数组、切片和Map
后端
专注仿真5 小时前
ThinkPHP6 API接口开发实例:从零搭建RESTful风格接口
后端·php·restful
开心猴爷5 小时前
应对iOS审核4.3:可以使用 IpaGuard 来给属性名混淆的技术细节与平衡之道
后端·ios
1m555555555 小时前
RAG 工程实战(五):正确知识已经进入 Prompt,为什么大模型还是会答错?
后端·面试
易小尊5 小时前
我的模型在 65% 以上时准得可怕,在 50% 时像在掷硬币
后端