sed 与 awk 实战:文本处理三剑客

发布时间:2026/10/2 8:13:20

sed 与 awk 实战:文本处理三剑客 sed 与 awk 实战文本处理三剑客 系列Shell 脚本系列第5篇 笔名厕所里的思想家—## 一、开篇引子在日常 Linux 运维和脚本开发中文本处理占到了日常工作量的 60% 以上。日志分析、配置修改、数据提取、格式转换——几乎每个任务都离不开对文本的操作。前面我们学了 Shell 脚本的基础语法、变量和流程控制但有没有遇到过这样的场景- 线上有个 200MB 的访问日志你想找出所有 500 错误的请求 IP 和访问时间- 一个配置文件里有 1000 行你需要批量修改其中某一类配置项- 从数据库导出的 CSV 文件你想筛选出某个字段满足条件的行再重新排序这些问题用标准 Shell 命令当然也能解决但用对工具效率是天壤之别。grep 是找sed 是改awk 是析。这三大工具组合起来几乎能处理任何文本任务。本篇不讲零碎语法直接上场景——每个场景都是你工作中大概率会遇到的问题跟着动手做一遍你就能掌握这三把利剑。—## 二、sed — 流编辑器批量修改文本### 2.1 sed 的核心哲学sed(Stream Editor) 的核心思想是逐行读取 → 匹配模式 → 执行操作。它不修改源文件除非加-i而是将处理结果输出到标准输出。基本语法bashsed [选项] 地址范围操作 文件### 2.2 场景 1批量替换 Nginx 配置中的域名nginx# 旧的 nginx.confserver_name old-domain.com;# 要把所有 old-domain.com 替换为 new-domain.com解法bashsed -i s/old-domain\.com/new-domain.com/g nginx.conf-i 是直接修改源文件s 是替换命令g 是全局替换每一行所有匹配位置不止第一处。**⚠️ 生产环境安全写法**bash# 先备份再修改sed -i.bak ‘s/old/new/g’ config.conf# 这样会生成 config.conf.bak 作为备份### 2.3 场景 2删除日志中的特定行假设你要清理 access.log 中的健康检查请求来自 k8s 的 /healthz 端点bash# 删除包含 /healthz 的行sed ‘//healthz/d’ access.log clean.logd是删除命令。多个模式可以用-ebashsed -e /\/healthz/d -e /\/metrics/d access.log clean.log### 2.4 场景 3只打印某个区间的行bash# 打印第 10 到第 20 行sed -n 10,20p file.log# -n 选项不自动打印只打印匹配的行# p 命令打印匹配的行### 2.5 场景 4在匹配行前后插入内容bash# 在包含 [server] 的行之前插入一行sed /\[server\]/i\# Server Configuration config.ini# 在包含 [server] 的行之后追加一行sed /\[server\]/a\timout 30 config.ini### 2.6 sed 的高级文本替换bash# 引用匹配内容反向引用echo helloworld | sed s/\([^]*\)\(.*\)/\2 \1/# 输出: world hello# 多模式替换sed -e s/ERROR/INFO/g -e s/WARN/INFO/g app.log# 只替换每行第二次出现的匹配sed s/,/|/2 data.csv # 每行第二个逗号换成 |** 核心口诀**s/旧/新/基础替换g全局替换-i直接写文件-n p只打印匹配行。---## 三、awk — 文本分析器结构化数据处理### 3.1 awk 的核心哲学awk的理念更接近数据库查询**把文本当表格行是记录列是字段**你可以按字段筛选、计算、格式化输出。基本语法bashawk [选项] BEGIN{前置命令} 条件 {行处理命令} END{后置命令} 文件每个字段用$1,$2, ... 引用$0代表整行。默认字段分隔符是空白空格/Tab。### 3.2 场景 5分析 access.log 统计各 IP 的访问量这是运维中最经典的需求bash# 假设日志格式IP - - [日期] 请求 状态码 大小# 192.168.1.1 - - [28/Jun/2026:10:00:00 0800] GET /api HTTP/1.1 200 1234awk {count[$1]} END {for (ip in count) print ip, count[ip]} access.log | sort -k2 -rn | head -10**分解**-{count[$1]}— 以第1列IP为键每出现一次计数1-END {…}— 文件处理完后执行-for…— 遍历字典输出 IP 和计数-sort -k2 -rn— 按第二列计数逆序排序-head -10— 取前 10### 3.3 场景 6筛选出 5xx 错误并格式化输出bashawk $9 ~ /^5[0-9][0-9]$/ {printf %-20s %-15s %s\n, $4, $1, $9} access.log输出[28/Jun/2026:10:00 192.168.1.1 500[28/Jun/2026:10:01 10.0.0.5 502**解释**-$9 ~ /^5…/— 第9列匹配 5xx 状态码-printf— 格式化输出%-20s左对齐占20字符### 3.4 场景 7CSV 文件数据提取与计算csv# employees.csvname,department,salary,years张三,技术部,15000,3李四,技术部,18000,5王五,市场部,12000,2赵六,市场部,14000,4**统计各部门平均工资**bashawk -F, NR1 {dept[$2]$3; count[$2]} END {for (d in dept) printf %s: %.2f (共%d人)\n, d, dept[d]/count[d], count[d]} employees.csv输出市场部: 13000.00 (共2人)技术部: 16500.00 (共2人)**关键点**--F,— 指定逗号为字段分隔符-NR1— 跳过标题行NR当前行号### 3.5 场景 8日志时间范围过滤bash# 筛选 10:00 到 10:59 之间的日志awk $4 ~ /^\[28\/Jun\/2026:10:/ access.log### 3.6 awk 内置变量速查| 变量 | 含义 ||:----|:----||NR| 已读取的记录数行号 ||NF| 当前行的字段数列数 ||$0| 整行内容 ||1..1..1..n| 第 1~n 个字段 ||FS| 字段分隔符默认空白 ||OFS| 输出字段分隔符默认空格 ||RS| 记录分隔符默认换行 |** 核心口诀**$1$2取字段{c[KaTeX parse error: Expected EOF, got } at position 5: 1]}̲ 做统计printf …(wc -l “$LOG_FILE”)echo “总请求数: $total”# 2. 状态码分布echo -e \n— 状态码分布 —“awk {codes[KaTeX parse error: Expected EOF, got } at position 5: 9]}̲ END {for (c in…LOG_FILE” | sort -k2 -rn# 3. 最活跃的前 10 个 IPecho -e “\n— 最活跃 IP Top 10 —“awk {ips[KaTeX parse error: Expected EOF, got } at position 5: 1]}̲ END {for (i in…LOG_FILE” | sort -rn | head -10 | awk {printf %-20s %d次\n”, $2, $1}‘# 4. 请求最多的 URL Top 10echo -e “\n— 最热 URL Top 10 —“awk {urlKaTeX parse error: Undefined control sequence: \? at position 10: 7; gsub(/\̲?̲.*/, , url); …LOG_FILE” | sort -rn | head -10 | awk {printf %-50s %d次\n”, $2,KaTeX parse error: Expected EOF, got } at position 2: 1}̲# 5. 4xx/5xx 错…(awk ‘9 /[45][0−9][0−9]9 ~ /^[45][0-9][0-9]9/[45][0−9][0−9]/’ “$LOG_FILE” | wc -l)echo -e \n— 错误分析 —echo 4xx/5xx 错误数: $errorsecho 错误率: $(echo “scale2; $errors * 100 /total∣bc)total | bc)%### 5.2 场景 12配置文件中批量修改参数bash#!/bin/bash# update_config.sh — 批量修改配置文件CONFIG/etc/myapp/config.ini# sed 批量修改sed -i.bak \ -e s/^debugfalse/debugtrue/ \ -e s/^port8080/port9090/ \ -e /^#.*database_url/s/^#// \ total∣bc)CONFIG”# awk 校验修改结果echo 修改后的关键配置 “awk -F ‘/^(debug|port|database_url)/’ “$CONFIG”### 5.3 场景 13多文件数据合并与分析bash# 合并多个服务器上的日志统计按小时的请求分布cat server1.log server2.log server3.log | \ awk ‘{split($4, arr, /[/:]/); hourarr[5]} {hourly[hour]} END {for (h in hourly) printf “%02d:00 → %d次\n”, h, hourly[h]}’ | \ sort### 5.4 场景 14实时监控与报警bash#!/bin/bash# monitor_5xx.sh — 实时监控 5xx 错误并报警tail -f /var/log/nginx/access.log | \ awk ‘9 /5[0−9][0−9]9 ~ /^5[0-9][0-9]9/5[0−9][0−9]/ { system(echo “[ALERT] 5xx错误: $0 “” | mail -s “告警: Nginx 5xx错误” adminexample.com”) printf “ [%s] 5xx错误: %s %s\n”, $4, $1, $9 }’—## 六、性能与效率对比| 场景 | sed | awk | grep | 推荐 ||:----|:—:—:—:----:|| 简单替换 | ⭐⭐⭐ | ⭐⭐ | — |sed|| 删除特定行 | ⭐⭐⭐ | ⭐⭐ | — |sed|| 统计聚合 | — | ⭐⭐⭐ | — |awk|| 字段筛选 | — | ⭐⭐⭐ | — |awk|| 正则搜索 | ⭐⭐ | ⭐⭐ | ⭐⭐⭐ |grep|| 上下文显示 | ⭐ | — | ⭐⭐⭐ |grep -C|| 复杂数据管道 | ⭐ | ⭐⭐⭐ | ⭐ |awk pipe|| 处理大文件(1GB) | ⭐⭐⭐ | ⭐⭐ | ⭐⭐⭐ |sed/grep|经验之谈能用 grep 解决的问题不要用 sed能用 sed 解决的不要用 awk。工具越专用效率越高。但当任务复杂到需要算的时候awk 是最趁手的。—## 七、常见的坑与避坑指南### 7.1 sed 中的正则转义bash# ❌ 错误特殊字符未转义sed ‘s/old.com/new.com/g’ file # . 会匹配任意字符# ✅ 正确转义点号sed ‘s/old.com/new.com/g’ file# 或者用扩展正则 (-E)sed -E ‘s/old.com/new.com/g’ file### 7.2 awk 中的 shell 变量传递bash# ❌ 错误shell 变量直接在 awk 中使用keyword“ERRORawk ‘0 /0 ~ /0/keyword/’ log # awk 不识别KaTeX parse error: Expected EOF, got # at position 8: keyword#̲ ✅ 正确使用 -v 传递变…keyword” ‘$0 ~ kw/’ log# 或者用单引号跳转awk 0 /′0 ~ /0/′keyword”’/’ log### 7.3 大文件处理bash# 处理超大文件时用管道避免中间文件# ❌ 差先 grep 写入中间文件grep “ERROR” huge.log errors.logawk ‘{count[$1]} END {for …}’ errors.log# ✅ 好管道直接传递grep “ERROR” huge.log | awk ‘{count[$1]} END {for …}’—## 八、总结| 工具 | 说人话 | 最擅长 ||:----|:------|:-------||grep| 文本搜索器 | 在文件堆里找东西 ||sed| 文本手术刀 | 批量替换、增删行 ||awk| 文本数据库 | 按列分析、统计、格式化 |这三把剑组合起来你在 Linux 下的文本处理能力就基本毕业了。下次遇到任何文本处理任务先问自己三个问题1. 要找人→grep2. 要改东西→sed 3. 要算数据→awk—下一篇预告Shell 调试技巧——告别脚本报错找不到原因
延伸阅读

更多相关文章

2026/10/2 8:13:20

Node.js + React 实战:构建有状态 AI Agent 的工程指南

1. 从 paperclip 说起:一个把 AI Agent 装进 Node.js 与 React 世界的工程实践第一次看到paperclip这个标题,我脑子里蹦出来的不是回形针办公用品,而是那个经典的“回形针助手”隐喻——一个能理解上下文、能主动帮你干活的智能体。结合热搜词…

2026/10/2 8:08:19

MLIR模型编译加速实战:从ONNX到高性能动态库的完整流水线

1. 从四处碰壁到真正提速:我为什么决定把推理链路整个交给MLIR 干推理优化这几年,有一个问题几乎每次都会被问到:模型部署时的性能瓶颈到底在哪?如果你的第一反应是“算子实现不够快”,那只能说答对了一小半。我自己的…

2026/10/2 9:03:23

模糊理论入门:用隶属度建模现实世界的灰色地带

1. 什么是模糊理论?它不是“不清晰”,而是处理“不精确”的精密工具 很多人第一次听到“模糊理论”四个字,下意识觉得这是个糊弄人的概念——都模糊了,还谈什么理论?我刚接触时也这么想,直到在工厂做设备故…

2026/10/2 9:03:23

计算机体系结构中的网络:从DMA到DPU的硬件/软件协同

提到“计算机体系结构”,大多数人的第一反应是CPU流水线、缓存一致性、存储层次这些硬核内容。等到教材翻到第七章“网络”时,很多人心里其实会犯嘀咕:网络不是《计算机网络》课该讲的东西吗,体系结构掺和进来算怎么回事&#xff…

2026/10/2 9:03:22

模糊控制工程落地指南:从隶属函数到Mamdani模型实战

1. 这不是数学课,是解决现实模糊问题的实用工具箱“模糊理论相关学习(1)”这个标题乍看像高校课程表里的一个编号,容易让人联想到黑板上密密麻麻的隶属函数曲线、一堆希腊字母堆砌的公式,以及“这到底有什么用”的困惑…

2026/10/2 9:03:22

Linux less命令完全指南:从日志排障到高效运维的必会利器

年后开工第一天,线上日志系统突然告警,我SSH到服务器上准备排查问题。文件20多G,cat直接会把终端刷到爆炸,vim打开会卡到怀疑人生。这时候我下意识敲下了 less 三个字母,然后轻车熟路地按 /ERROR 搜索、按 & …

2026/10/2 9:03:22

SpringBoot+Vue财务管理系统:源码拆解、部署与二次开发指南

简介:一份基于SpringBootVue的财务管理系统完整资源包,面向需要进行课程设计或毕业设计的Java全栈学习者,覆盖企业财务流水、采购、销售、资产等核心管理场景。资源共450个文件,压缩包约17.63MB,以svg图标、java后端代…

2026/10/2 8:58:22

多模态手势识别系统:视觉与IMU融合的工程落地与避坑指南

简介:该资源是一套基于MATLAB实现的多模态信号融合手势识别系统,面向计算机、电子信息工程、数学等专业的大学生及研究人员,可用于课程设计、期末大作业、毕业设计或相关课题研究。系统融合视觉、深度、声音等多种信号,通过早期融…

2026/10/2 8:16:46

东莞市品牌网站建设报价常见报错与解决

东莞品牌网站建设报价单背后:一份保姆级建站教程避坑实录 网站做好了没人访问,这大概是很多老板最头疼的事。花了大几万做的品牌站,上线后流量惨淡,比路边摊还冷清。别急着骂外包公司,很多“东莞品牌网站建设报价”里藏着不少猫腻,比如用模板站冒充定制…

2026/10/1 17:09:46

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/10/1 10:48:55

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/10/2 0:02:57

PWN入门:从栈溢出原理到ROP链实战

1. 这不是“学PWN”,是重新理解你每天敲的每一行C代码我第一次在CTF赛场上写出能控制程序流的exp时,手抖得连gdb的c命令都输错三次。那道题只有23行C代码,一个gets()调用,一个printf(),一个return——它甚至没开NX&…

2026/10/2 0:02:57

Windows下cudaMallocHost显存占用之谜:WDDM与TCC模式差异及优化方案

1. 一个反直觉的显存占用现象第一次在 Windows 上看到cudaMallocHost把显存吃掉的时候,我的反应是打开任务管理器反复确认了三遍。明明调用的是主机端锁页内存分配,按 CUDA 文档的说法,这块内存应该落在系统 RAM 里,跟 GPU 的显存…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑