sed 是 Linux 文本处理的瑞士军刀,不用打开文件就能完成替换、删除、插入。本文用 20 个生产环境真实案例,从入门到进阶,手把手教你用 sed 高效处理文本。
一、sed 基础语法
sed [选项] '命令' 文件名sed [选项] -e '命令1' -e '命令2' 文件名
核心概念
|
|
|
| 模式空间 |
|
| 地址 |
|
| 命令 |
|
| -i |
直接修改文件(in-place),不加则输出到屏幕
|
二、20 个实战案例
案例1:基础替换(每行第一个匹配)
# 将文件中的 "localhost" 替换为 "127.0.0.1"sed 's/localhost/127.0.0.1/' config.ini# 直接修改文件sed -i 's/localhost/127.0.0.1/' config.ini
案例2:全局替换(每行所有匹配)
# 加 g 标志,替换所有出现sed 's/foo/bar/g' file.txt# 替换第2次及以后的出现sed 's/foo/bar/2g' file.txt
案例3:替换特定行
# 只替换第3行sed '3s/foo/bar/' file.txt# 替换第3到第5行sed '3,5s/foo/bar/' file.txt# 替换最后一行sed '$s/foo/bar/' file.txt
案例4:正则匹配替换
# 替换以 # 开头的行(注释行)sed 's/^#.*//' nginx.conf# 替换包含 "error" 的行sed '/error/s/500/502/' log.txt# 替换 IP 地址格式sed 's/[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+/0.0.0.0/g' access.log
案例5:使用分隔符(避免转义)
# 路径替换,用 # 代替 /,避免转义sed 's#/usr/local/bin#/opt/bin#g' script.sh# 或用 |sed 's|/usr/local/bin|/opt/bin|g' script.sh
案例6:删除空行
# 删除空行sed '/^$/d' file.txt# 删除只有空格的行sed '/^[[:space:]]*$/d' file.txt
案例7:删除注释行
# 删除 # 开头的注释行sed '/^#/d' nginx.conf# 删除 // 开头的注释行(C/Java 风格)sed '/^[[:space:]]*\/\//d' code.java
案例8:删除特定行
# 删除第5行sed '5d' file.txt# 删除第3到第10行sed '3,10d' file.txt# 删除包含 "DELETE" 的行sed '/DELETE/d' sql.log# 删除最后一行sed '$d' file.txt
案例9:行首插入内容
# 每行前面加注释sed 's/^/# /' file.txt# 第1行前插入标题sed '1i\# 配置文件' nginx.conf# 所有行前面加制表符sed 's/^/\t/' file.txt
案例10:行尾追加内容
# 每行末尾加分号sed 's/$/;/' code.c# 最后一行追加新配置sed '$a\server_name example.com;' nginx.conf
案例11:在匹配行后插入
# 在包含 "listen 80" 的行后插入sed '/listen 80/a\ listen 443 ssl;' nginx.conf# 在包含 "location /" 的行后插入多行sed '/location \/ {/a\ proxy_pass http://backend;\n proxy_set_header Host $host;' nginx.conf
案例12:在匹配行前插入
# 在包含 "server {" 的行前插入注释sed '/server {/i\# 主服务器配置' nginx.conf
案例13:替换特定行范围
# 替换第5到第10行的所有 foosed '5,10s/foo/bar/g' file.txt# 从第3行到文件末尾sed '3,$s/foo/bar/g' file.txt# 从匹配 "START" 到匹配 "END" 的行sed '/START/,/END/s/foo/bar/g' file.txt
案例14:打印特定行
# 打印第5行(-n 抑制默认输出)sed -n '5p' file.txt# 打印第5到第10行sed -n '5,10p' file.txt# 打印包含 "ERROR" 的行sed -n '/ERROR/p' log.txt# 打印最后一行sed -n '$p' file.txt
案例15:提取替换结果
# 只输出替换后的行sed -n 's/foo/bar/p' file.txt# 输出替换成功的行号sed -n 's/foo/bar/=' file.txt
案例16:备份修改
# -i 直接修改前备份sed -i.bak 's/foo/bar/g' file.txt# 生成 file.txt.bak 备份文件
案例17:多命令组合
# 删除空行并替换 localhostsed -e '/^$/d' -e 's/localhost/127.0.0.1/g' config.ini# 或使用分号sed '/^$/d; s/localhost/127.0.0.1/g' config.ini
案例18:从文件读取命令
# 将多个 sed 命令写在文件里cat > sed_commands.txt << 'EOF'/^$/ds/localhost/127.0.0.1/gs/8080/80/gEOF# 执行sed -f sed_commands.txt config.ini
案例19:处理多个文件
# 批量修改当前目录所有 .conf 文件sed -i 's/localhost/127.0.0.1/g' *.conf# 递归修改(配合 find)find /etc/nginx -name "*.conf" -exec sed -i 's/localhost/127.0.0.1/g' {} +
案例20:高级:使用捕获组
# 交换两个字段(逗号分隔)echo "John,Doe" | sed 's/\([^,]*\),\([^,]*\)/\2,\1/'# 输出:Doe,John# 提取日期格式 YYYY-MM-DD 并改为 DD/MM/YYYYecho "2026-07-15" | sed 's/\([0-9]\{4\}\)-\([0-9]\{2\}\)-\([0-9]\{2\}\)/\3\/\2\/\1/'# 输出:15/07/2026# 给每行加引号sed 's/.*/"&"/' file.txt
三、sed 与正则表达式
|
|
|
^ |
|
$ |
|
. |
|
* |
|
\+ |
|
\? |
|
.* |
|
[] |
|
[^] |
|
\(\) |
|
\1\2 |
|
使用扩展正则(更简洁):
# -r 启用扩展正则,不用转义括号echo "John,Doe" | sed -r 's/([^,]*),([^,]*)/\2,\1/'
四、生产环境实战
场景1:批量修改服务器配置
#!/bin/bash# 批量修改所有服务器的 Nginx 配置SERVERS="web1 web2 web3"for server in $SERVERS; do ssh $server " sudo sed -i 's/worker_processes 4/worker_processes auto/' /etc/nginx/nginx.conf sudo sed -i '/keepalive_timeout/s/65/30/' /etc/nginx/nginx.conf sudo nginx -t && sudo systemctl reload nginx "done
场景2:日志脱敏
# 将日志中的手机号、身份证号脱敏sed -i \ -e 's/[0-9]\{11\}/***********/g' \ -e 's/[0-9]\{6\}[0-9]\{8\}[0-9]\{4\}/**************/g' \ access.log
场景3:提取关键信息
# 从配置文件提取所有 server_namesed -n 's/.*server_name \(.*\);/\1/p' nginx.conf# 从日志提取所有 IPsed -n 's/.*client \([0-9.]*\).*/\1/p' /var/log/secure
场景4:清理旧数据
# 删除配置文件中的旧注释和空行sed -i \ -e '/^[[:space:]]*#/d' \ -e '/^[[:space:]]*$/d' \ -e 's/[[:space:]]*$//' \ config.ini
五、sed vs awk vs grep 选型
# 组合使用grep "ERROR" app.log | sed 's/ERROR/WARNING/' | awk '{print $1, $5}'
六、常见错误
|
|
|
|
sed: -e expression #1, char 10: unknown command |
|
|
|
|
|
sed -i
|
|
|
|
|
|
|
\n
|
|
七、总结 checklist
□ s/old/new/ 基础替换,加 g 全局替换□ s/old/new/2 只替换第2个,s/old/new/2g 从第2个开始□ /^pattern/d 删除匹配行,/^$/d 删除空行□ 1i\text 第1行前插入,$a\text 最后追加□ /pattern/a\text 匹配行后追加□ -i 直接修改,-i.bak 修改前备份□ -n + p 只打印匹配行□ \(\) 捕获组,\1 \2 引用□ -r 扩展正则,减少转义□ -e 多命令组合,-f 从文件读取命令
一句话总结
sed 是文本处理的手术刀:不打开文件、不加载内存、管道流式处理,适合日志清洗、配置批量修改、数据脱敏等场景。记住:s 替换、d 删除、a/i 插入,三个命令覆盖 80% 的需求。