Linux 文本处理三剑客:sed使用教程

介绍

sed(stream editor)流编辑器,​按行读取文本、处理后输出​,默认不修改原文件,只输出到标准输出。 核心:sed [选项] '脚本' 文件名

应用场景

​非交互式、按行处理文本,适合脚本自动化

  1. ​配置文件自动化维护​:批量替换 IP / 域名 / 端口、增删注释、插入 / 删除配置行(部署脚本高频)
  2. ​日志清洗​:过滤指定日志行、截取时间段日志、清理多余空白,大文件流式读取省内存
  3. ​批量多文件文本替换​:项目内批量修改代码、文档内容,搭配 find 批量处理
  4. ​管道数据预处理​:对命令输出做提取、裁剪,作为 grep/awk 的前置文本加工
  5. ​文本格式修正​:换行符转换、去除首尾空格、字符映射转换

一、常用选项

参数 说明
-n 只输出匹配到的行,不打印所有行(常用)
-e 追加多个编辑命令,多个表达式
-f file 从文件读取sed脚本
-i ​直接修改原文件​(高危!建议先用 -i.bak 备份)
-r / -E 使用扩展正则表达式(不用转义 `()+?

⚠️ -i.bak:修改原文件,同时生成 xxx.bak 备份文件,生产环境强烈推荐。

二、sed 脚本语法

格式:[地址]命令[参数]

  • ​地址​:限定哪些行执行命令;没有地址=所有行
    • 数字:3 第3行;3,5 3~5行
    • /正则/:匹配正则的行
    • $:最后一行
    • 3,$:第3行到末尾
  • ​命令​:增删改查

基础命令速查表

命令 全称 作用
p print 打印行,配合 -n
d delete 删除行
s substitute 替换(最常用)
a append 行后追加文本
i insert 行前插入文本
c change 替换整行
y translate 字符一对一转换
q quit 匹配后退出sed

三、基本使用

准备文件

执行下面命令,创建测试文本文件:test.txt

cat > test.txt <<EOF
apple 100
banana 200
orange 300
apple 400
EOF

1. 打印(p),搭配 -n

# 打印第2行
sed -n '2p' test.txt

# 打印2~3行
sed -n '2,3p' test.txt

# 打印最后一行
sed -n '$p' test.txt

# 匹配包含apple的行
sed -n '/apple/p' test.txt

# 从第2行开始,直到匹配orange停止
sed -n '2,/orange/p' test.txt

2. 删除行 d

只是输出删除,原文件不变,加-i才改文件

# 删除第1行
sed '1d' test.txt

# 删除1~2行
sed '1,2d' test.txt

# 删除最后一行
sed '$d' test.txt

# 删除包含banana的行
sed '/banana/d' test.txt

# 删除空行
sed '/^$/d' test.txt

3. 替换 s/// (重要)

语法:s/查找内容/替换内容/标记

标记:

  • g:global 全局替换(一行内所有匹配,不加g只替换第一个)
  • i:忽略大小写
  • p:打印匹配行(配合-n)
  • w file:把匹配行写入文件
# 把apple换成pear,每行只替换第一个
sed 's/apple/pear/' test.txt

# 全局替换所有apple
sed 's/apple/pear/g' test.txt

# 忽略大小写替换
sed 's/apple/pear/gi' test.txt

# 使用#作为分隔符(路径替换时好用,避免/转义)
sed 's#/usr/bin#/usr/local/bin#g'

# 只输出替换成功的行
sed -n 's/apple/pear/gp' test.txt

分组捕获(扩展正则 -E)\1 代表第一个括号匹配内容

# 提取单词,分组
echo "abc123def" | sed -E 's/([a-z]+)([0-9]+)([a-z]+)/\1_\2_\3/'
# 输出 abc_123_def

4. 插入、追加、整行替换 i a c

# i:第2行前面插入一行 hello
sed '2i hello' test.txt

# a:第2行后面插入一行 hello
sed '2a hello' test.txt

# c:把第2行整行替换成 hello
sed '2c hello' test.txt

# 在匹配apple的行后面追加
sed '/apple/a add_line' test.txt

5. 字符转换 y

一对一字符映射,不是正则!

# a→A,b→B,1→!
echo "a1b" | sed 'y/ab1/AB!/'
# A!B

6. 多命令执行

方式1:-e
sed -e 's/apple/APPLE/g' -e '/banana/d' test.txt
方式2:分号 ;
sed 's/apple/APPLE/g;/banana/d' test.txt

7. 修改原文件 -i

# 推荐:修改,并且备份 test.txt.bak
sed -i.bak 's/apple/pear/g' test.txt

# 不备份,直接修改(GNU sed,MacOS不推荐)
sed -i 's/apple/pear/g' test.txt

MacOS 注意:sed -i '' 'xxx' file,必须加空引号。

8. 退出 q

找到匹配行就停止读取文件,提升大文件性能

sed '/orange/q' test.txt

四、正则在sed里的使用

sed 默认基础正则:^ $ . * [],() {} + ? | 需要转义 \( \) \{ \}加 -E(GNU sed)启用扩展正则,不用转义:

  • ^ 行开头
  • $ 行结尾
  • . 任意单个字符
  • * 前面字符0次或多次
  • + 1次以上(-E)
  • ? 0或1次(-E)
  • | 或(-E)
  • () 分组(-E)

示例:

# 删除以#开头的注释行
sed '/^#/d' test.txt

# 删除空格+#开头注释行
sed -E '/^[[:space:]]*#/d' test.txt

# 去掉行尾空白
sed -E 's/[[:space:]]+$//' test.txt

[[:space:]] 匹配空格、tab,POSIX标准,比 \s 兼容性更好。

五、实用高频脚本

# 1. 删除注释行和空行
sed -E '/^[[:space:]]*#/d; /^$/d' nginx.conf

# 2. 批量替换文件内容(带备份)
sed -i.bak 's/old_str/new_str/g' *.conf

# 3. 在文件第一行插入文字
sed -i '1i # new header' test.txt

# 4. 在文件末尾追加文字
sed -i '$a # end line' test.txt

# 5. 提取ip(示例)
echo "192.168.1.100 server" | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+).*/\1/'

# 6. 去掉每行开头空格
sed -E 's/^[[:space:]]+//' test.txt

六、sed 工作原理

  1. 读取一行到​模式空间​(pattern space)
  2. 执行sed脚本命令处理模式空间内容
  3. 默认打印模式空间,清空,继续读下一行

    保持空间(hold space)高级用法:h H g G x,用于多行处理。

高级:保持空间简单示例(多行处理)

# h:模式空间复制到保持空间;G:保持空间追加到模式空间
sed '/apple/h;${x;p}' test.txt

七、坑点总结

  1. sed 默认​不修改原文件​,必须 -i;优先 -i.bak
  2. 不加 g,替换只替换一行中第一个匹配
  3. / 作为分隔符,替换路径建议改用 s#xxx#yyy#
  4. MacOS sed 是BSD sed,和GNU sed有差异(-i参数、正则)
  5. 地址范围 start,end:start匹配后开始,end匹配后结束,后续重新寻找start

原文出处:/show_1GW42fmzueqn.html