1. 为什么你需要掌握sed第一次接触sed时我也觉得这个命令行工具看起来晦涩难懂。直到有次需要处理一个500MB的日志文件用文本编辑器直接打开卡死用Excel根本加载不了这时候sed只用一行命令就搞定了数据清洗我才真正体会到它的威力。sed全称Stream EDitor流编辑器是Unix/Linux系统自带的文本处理神器。它最大的特点是逐行处理数据流不会一次性加载整个文件所以处理大文件时内存占用极低。我处理过2GB的CSV文件sed依然游刃有余这是GUI编辑器根本无法比拟的。在实际工作中这些场景你一定会用到sed批量修改服务器配置文件中的IP地址从杂乱日志中提取关键错误信息快速清理CSV文件中的异常格式自动化脚本中的文本预处理2. 基础语法从hello world开始2.1 基本命令结构sed命令的标准格式就像下面这样sed [选项] 操作指令 文件名最简单的例子我们要把文本中的world替换为sedecho hello world | sed s/world/sed/ # 输出hello sed这里用到了s替换命令它的完整格式是s/旧内容/新内容/。记住这个模式它能解决你80%的文本替换需求。2.2 必须掌握的四个选项刚开始用sed时我建议先掌握这四个最常用的选项-n静默模式只输出处理过的行。配合p命令可以精确控制输出内容seq 1 5 | sed -n 3p # 只输出第三行-i直接修改文件内容慎用。不加这个选项时sed只是输出处理结果不会改原文件sed -i s/old/new/g file.txt # 真正修改文件-e执行多条命令。比如先删除空行再替换内容sed -e /^$/d -e s/foo/bar/ file.txt-r使用扩展正则表达式。写复杂匹配规则时会方便很多echo abc123 | sed -r s/[a-z]// # 输出1233. 定位技巧精确到行和字符3.1 行号定位处理日志文件时经常需要针对特定行操作。sed支持多种定位方式sed 5d file.txt # 删除第5行 sed 3,7s/old/new/ # 只修改3到7行 sed $d file.txt # 删除最后一行$表示末尾 sed 2~3d access.log # 从第2行开始每隔3行删除一行适合采样3.2 正则定位更灵活的方式是用正则表达式定位sed /error/d app.log # 删除所有含error的行 sed /^#/d config.conf # 删除所有注释行以#开头 sed /start/,/end/d # 删除从含start到含end的所有行我曾经用这个特性快速清理过nginx配置sed -i /^$/d;/#.*$/d nginx.conf # 删除空行和注释4. 高阶替换技巧4.1 分组捕获与引用这是sed最强大的功能之一。假设我们要把2023-01-15格式转为01/15/2023echo 2023-01-15 | sed -r s/([0-9]{4})-([0-9]{2})-([0-9]{2})/\2\/\3\/\1/解释()捕获分组\1引用第一个分组-r启用扩展正则支持{}等元字符4.2 特殊替换技巧大小写转换echo Hello World | sed s/\(.*\)/\L\1/ # 转小写 echo hello world | sed s/\(.*\)/\U\1/ # 转大写保留匹配部分echo price: $99 | sed s/price: \(\$[0-9]*\)/\1/ # 输出$99非贪婪匹配需要Perl模式echo foo bar baz | sed -E s/(.*?)bar/\1BAR/ # 替换第一个bar5. 实战案例解析5.1 日志清洗实战假设有个web日志片段127.0.0.1 - - [10/Oct/2023:13:55:36] GET /api/user HTTP/1.1 200 432 127.0.0.1 - - [10/Oct/2023:13:55:37] POST /api/login HTTP/1.1 200 342我们需要提取时间、方法和路径cat access.log | sed -E s/.*\[(.*)\].*(GET|POST) (\/[^ ]*).*/\1 \2 \3/5.2 批量修改配置有100台服务器的配置文件需要更新Redis地址sed -i s/redis_host: .*/redis_host: 10.0.0.123/ /etc/app/*.conf5.3 CSV格式转换原始数据name,age,gender John,25,M Lisa,30,F转为Markdown表格sed 1s/^/| /;1s/,/ | /g;1s/$/ |/;2,$s/^/| /;2,$s/,/ | /g;2,$s/$/ |/ data.csv6. 高级技巧与性能优化6.1 多命令组合用{}组合多个操作比如删除空行并转换大小写sed /^$/{d; s/.*/\L/} file.txt6.2 保持空间操作sed有两个缓冲区模式空间当前处理的行保持空间临时存储区用h/H/g/G可以在两者间交换数据。比如实现行号标记sed file.txt | sed N;s/\n/ / # 给每行添加行号6.3 处理大文件技巧禁用缓冲GNU sed特有sed -u s/foo/bar/ huge.log只处理匹配到的行sed /pattern/!d bigfile.txt output.txt配合split分块处理split -l 1000000 bigfile.txt chunk_ for f in chunk_*; do sed -i s/old/new/ $f; done7. 常见坑与解决方案MacOS与Linux的sed差异Mac的sed需要加和-E替代-r# Linux sed -i s/foo/bar/ file # Mac sed -i -E s/foo/bar/ file特殊字符转义echo /path/to/file | sed s/\//\\\//g # 转义斜杠贪婪匹配问题echo foo bar baz | sed s/foo.*baz/FOO BAR BAZ/ # 整行替换性能陷阱避免在循环中反复调用sed复杂操作尽量用单个sed命令完成8. 与其他工具配合8.1 sedawk黄金组合提取nginx日志中的异常状态码awk $9400 {print} access.log | sed -E s/.*\[(.*)\].*/\1/8.2 sedgrep管道处理统计错误出现次数grep -i error app.log | sed s/.*\(ERROR [a-z]*\).*/\1/ | sort | uniq -c8.3 在Shell脚本中的应用自动化部署脚本示例#!/bin/bash OLD_IP192.168.1.100 NEW_IP$(curl -s ifconfig.me) sed -i s/$OLD_IP/$NEW_IP/g /etc/nginx/conf.d/*.conf systemctl reload nginx掌握sed后你会发现很多原本需要写Python脚本处理的任务用几行sed命令就能搞定。刚开始可能需要查手册但经过20-30次实践后这些命令就会变成你的肌肉记忆。建议保存这篇文章的代码片段遇到实际问题时直接拿来修改使用。