sed
sed(Stream Editor,流编辑器)是 Linux 文本处理三大神器之一(grep、sed、awk)。
它最大的特点是:
按行读取文本,对每一行执行编辑操作(替换、删除、插入、追加等),默认输出到标准输出,不修改原文件。
很多运维、开发、CI/CD、日志处理、配置修改都会用到 sed。
一、sed 工作原理
假设文件:
hello
world
linux
执行:
sed 's/world/chatgpt/' file.txt
输出:
hello
chatgpt
linux
但是原文件:
hello
world
linux
没有变化。
除非使用:
sed -i 's/world/chatgpt/' file.txt
二、sed 最重要命令:s(替换)
这是 90% 的 sed 使用场景。
语法:
sed 's/旧内容/新内容/'
例如:
echo "hello world" | sed 's/world/linux/'
输出:
hello linux
全局替换(g)
默认:
echo "a a a" | sed 's/a/b/'
结果:
b a a
只替换第一个。
全部替换:
echo "a a a" | sed 's/a/b/g'
输出:
b b b
替换指定第几个
例如:
echo "a a a a" | sed 's/a/b/2'
输出:
a b a a
只替换第二个。
三、直接修改文件(-i)
生产环境最常用。
例如:
配置:
port=8080
修改:
sed -i 's/8080/9090/' config.conf
结果:
port=9090
批量修改
find . -name "*.conf" |
xargs sed -i 's/dev/prod/g'
四、按行号操作
打印指定行
例如:
sed -n '5p' file.txt
表示:
打印第5行。
打印:
10~20行:
sed -n '10,20p' file.txt
最后一行:
sed -n '$p' file.txt
五、删除行(d)
例如:
删除第3行:
sed '3d' file.txt
删除:
10~20行:
sed '10,20d' file.txt
删除空行:
sed '/^$/d' file.txt
删除注释:
sed '/^#/d' config.conf
删除空白+注释:
sed '/^\s*#/d;/^$/d' config.conf
六、插入、追加、替换整行
行前插入(i)
sed '3i\
hello
' file.txt
第3行前:
line1
line2
hello
line3
行后追加(a)
sed '3a\
hello
' file.txt
整行替换(c)
sed '3c\
new line
' file.txt
七、只处理匹配行
例如:
日志:
INFO
ERROR
WARN
只替换 ERROR:
sed '/ERROR/s/ERROR/FATAL/' log.txt
结果:
INFO
FATAL
WARN
八、正则表达式
开头
sed '/^root/d'
删除:
root
root123
结尾
sed '/.log$/d'
删除:
app.log
包含数字
sed '/[0-9]/d'
多空格压缩
例如:
a b
变:
a b
sed 's/ */ /g'
或者:
sed 's/[[:space:]]\+/ /g'
九、引用变量
例如:
name=Tom
错误:
sed 's/USER/$name/'
不会展开变量。
正确:
sed "s/USER/$name/"
双引号。
十、替换路径
例如:
路径:
/usr/local/bin
如果:
sed 's//usr/local//opt/'
因为 / 冲突。
推荐:
sed 's#/usr/local#/opt#g'
或者:
sed 's|/usr/local|/opt|g'
任何字符都可以做分隔符。
十一、sed + find(生产经典)
修改所有 yaml:
find . -name "*.yaml" \
-exec sed -i 's/dev/prod/g' {} \;
或者:
find . -name "*.yaml" -print0 |
xargs -0 sed -i 's/dev/prod/g'
十二、sed + grep
例如:
日志:
grep ERROR app.log |
sed 's/ERROR/[ERROR]/'
输出:
[ERROR]
十三、sed + awk
例如:
ps -ef |
grep nginx |
sed 's/^ *//' |
awk '{print $2}'
得到 PID。
十四、生产环境高频案例
修改 nginx 配置
原:
listen 80;
修改:
sed -i 's/listen 80;/listen 8080;/'
修改 IP
sed -i 's/10.0.0.1/10.0.0.2/g'
修改 Docker Compose
sed -i 's/image:.*/image: nginx:1.27/'
修改 Kubernetes YAML
sed -i 's/replicas: 1/replicas: 3/'
删除空白
sed '/^$/d'
去掉 DOS 换行(CRLF → LF)
sed 's/\r$//'
去掉行尾空格
sed 's/[[:space:]]*$//'
去掉行首空格
sed 's/^[[:space:]]*//'
去掉首尾空格
sed 's/^[[:space:]]*//;s/[[:space:]]*$//'
十五、常用选项
| 选项 | 作用 | 示例 |
|---|---|---|
-n |
不自动打印 | sed -n '5p' |
-i |
原地修改 | sed -i 's/a/b/' |
-e |
多条命令 | sed -e 's/a/b/' -e '/^#/d' |
-f |
从脚本读取 | sed -f script.sed |
-E(GNU 也支持 -r) |
使用扩展正则 | sed -E 's/[0-9]+/NUM/' |
十六、GNU sed 与 BSD sed(macOS)区别
这是面试和跨平台开发经常踩坑的地方。
Linux(GNU sed)
sed -i 's/a/b/' file
macOS(BSD sed)
必须指定备份扩展名(可以为空):
sed -i '' 's/a/b/' file
或者生成备份:
sed -i .bak 's/a/b/' file
编写跨平台脚本时需要特别注意这一点。
十七、sed 常用命令速查
| 命令 | 功能 | 示例 |
|---|---|---|
s |
替换 | s/a/b/g |
d |
删除 | 3d |
p |
打印 | 5p |
i |
插入 | 3i text |
a |
追加 | 3a text |
c |
替换整行 | 3c text |
g |
全局替换标志 | s/a/b/g |
十八、什么时候用 sed?
| 场景 | 推荐工具 |
|---|---|
| 文本替换、配置修改 | ✅ sed |
| 日志过滤 | grep + sed |
| 提取字段、统计 | awk |
| 查找文件 | find |
| 批量处理文件 | find + xargs + sed |
| 一次性修改大量配置 | sed -i |
十九、生产环境黄金模板
批量修改配置
find /etc/myapp -name "*.conf" -print0 |
xargs -0 sed -i 's/debug=true/debug=false/g'
删除注释和空行
sed '/^[[:space:]]*#/d;/^$/d' config.conf
提取指定范围
sed -n '100,150p' app.log
清理日志格式
sed 's/\r$//;s/[[:space:]]*$//'
修改 YAML 中的镜像版本
sed -i 's#image: nginx:.*#image: nginx:1.27#'
总结
可以把 sed 的能力归纳为四类:
- 替换(
s):最常见,用于配置修改、日志格式化、批量替换。 - 过滤(
d、-n p):按行号或正则删除、打印指定内容。 - 编辑(
i、a、c):在指定位置插入、追加或替换整行。 - 批处理:与
find、xargs、grep等工具组合,对大量文件进行自动化处理。
对于日常运维和开发来说,掌握 s(替换)+ 正则 + -i(原地修改)+ -n(按需输出)+ find/xargs 组合,基本可以覆盖 90% 以上的 sed 使用场景。

浙公网安备 33010602011771号