目录

sed 命令使用详细总结

sed 命令使用详细总结

sed(Stream Editor)是Linux/Unix生态下的非交互式流编辑器,是文本处理三剑客(grep/sed/awk)核心成员,以逐行流式处理为核心,无需打开文件即可完成批量文本修改、过滤、提取等操作,是自动化脚本、运维文本处理的核心工具。

一、核心执行原理(必懂)

sed的处理逻辑全程围绕两个核心缓冲区展开,理解这一点就能彻底搞懂sed的工作模式:

  • 模式空间(Pattern Space):主处理缓冲区,逐行读取文本后载入此处,所有编辑命令默认仅作用于此,处理完一轮即清空

  • 保持空间(Hold Space):辅助暂存缓冲区,编辑命令无法直接作用,仅用于和模式空间交互数据,用于多行处理等高级场景

核心执行流程:

  1. 读取一行文本,去除换行符后载入模式空间

  2. 按「地址定位规则」匹配当前行,匹配成功则执行对应的编辑命令

  3. 命令执行完成后,默认将模式空间内容(恢复换行符)输出到标准输出

  4. 清空模式空间,读取下一行,循环直至文件结束

关键提示:sed默认不修改原文件,仅输出处理结果到终端,只有加-i选项才会直接修改原文件(高危操作)。

二、基础语法与命令格式


# 核心语法
sed [选项] '地址定位+编辑命令' 输入文件/标准输入

# 常用扩展格式
sed [选项] -e '指令1' -e '指令2' 目标文件  # 多命令串行执行
sed [选项] -f 脚本文件 目标文件             # 从脚本文件读取sed命令
sed [选项] '地址{命令1;命令2;...}' 文件     # 同地址多命令组合执行

三、高频核心选项

选项 全称 核心作用 高频使用场景 注意事项
-n --quiet/--silent 取消默认输出,仅打印指令主动处理的结果 精准提取指定行、仅输出替换成功的行 必须和p打印命令配合使用,否则无输出
-i[SUFFIX] --in-place 直接修改原文件,可选备份 批量修改配置文件、文本内容 高危操作!-i.bak会先备份原文件为file.bak;macOS(BSD sed)必须指定备份后缀,无备份需写-i ''
-e --expression 指定多个编辑指令,多命令串联 同时执行替换、删除、插入等多个操作 单条命令可省略,多条命令必须每个指令前加-e
-E/-r --regexp-extended 启用扩展正则表达式(ERE) 复杂正则匹配、分组、或逻辑` `
-f --file 从指定脚本文件读取sed命令 复杂逻辑、多命令批量执行 脚本文件中每行写一条sed命令,无需加单引号
-z --null-data 按NULL字符(\0)分割行,而非换行符 处理含换行符的单行文本、JSON内容 GNU sed特有扩展

四、地址定位(sed的灵魂)

sed的所有编辑命令,都可通过地址定位指定作用的行,不指定则默认作用于所有行。地址定位分为6大类,覆盖全场景。

1. 单地址定位


sed '5d' file.txt          # 作用于第5行,删除第5行
sed '$p' file.txt          # 作用于最后一行($代表最后一行),仅打印最后一行
sed '/error/p' file.txt    # 作用于匹配正则error的所有行,打印匹配行
sed '/^#/d' file.txt       # 作用于以#开头的行,删除注释行

2. 连续范围地址定位


sed '2,5d' file.txt        # 作用于第2到第5行(闭区间,包含首尾)
sed '3,+4d' file.txt       # 作用于第3行及后面4行(3-7行)
sed '/start/,/end/d' file.txt  # 作用于匹配start的行 到 匹配end的行 之间的所有行
sed '5,/pattern/p' file.txt    # 作用于第5行 到 匹配pattern的行 之间的所有行

3. 步进地址定位(GNU sed特有)

语法:起始行~步长


sed '1~2d' file.txt        # 奇数行删除(1,3,5...)
sed '2~2d' file.txt        # 偶数行删除(2,4,6...)
sed '0~3s/old/new/g' file.txt  # 每3行执行一次替换(3,6,9...)

4. 取反地址定位

语法:地址!命令


sed '2,5!d' file.txt       # 除了2-5行,其他行全部删除
sed '/error/!d' file.txt   # 除了匹配error的行,其他行全部删除

5. 分组地址(多命令绑定)

对同一地址执行多个命令,用{}包裹,命令用分号分隔


sed '/error/{s/ERROR/error/g;p;w error.log}' file.txt
# 匹配error的行:先替换大小写,再打印,最后写入error.log文件

五、核心编辑命令(高频必背)

按使用频率排序,覆盖99%日常场景,重点掌握替换命令。

5.1 替换命令 s(使用率70%+,核心中的核心)

语法:


s/正则匹配模式/替换内容/标志位

核心说明:

  • 分隔符/可自定义(# @ |等),避免路径中/冲突

  • 替换内容中可使用反向引用、特殊转义、匹配内容引用

核心标志位flags

标志位 核心作用 示例
g 全局替换,默认仅替换每行第一个匹配项 sed 's/old/new/g' file 替换每行所有old为new
数字N 替换每行第N个匹配项 sed 's/old/new/3' file 替换每行第3个old
p 打印替换成功的行,必须配合-n使用 sed -n 's/old/new/gp' file 仅输出替换后的行
i/I 匹配时忽略大小写 sed 's/old/new/gi' file 全局替换,忽略大小写
w 文件名 将替换成功的行写入指定文件 sed 's/old/new/gw output.log' file

替换进阶用法

  1. 自定义分隔符(处理路径/URL)

sed 's#/home/user#/opt/data#g' file.txt  # 用#替代/,避免路径转义
  1. &引用匹配到的完整内容

sed 's/[0-9]\+/(&)/g' file.txt  # 给所有数字加上括号,&代表匹配到的数字
sed 's/^.*$/【&】/g' file.txt    # 给每行内容加上【】包裹
  1. 分组与反向引用

基础正则(BRE)中分组用(),扩展正则(ERE)用(),反向引用用\1 \2…对应第N个分组


# 示例:将 "name:张三 age:20" 转为 "张三:20"
sed 's/name:\(.*\) age:\(.*\)/\1:\2/g' file.txt
# 启用扩展正则,省去转义符
sed -E 's/name:(.*) age:(.*)/\1:\2/g' file.txt
  1. 大小写转换(GNU sed特有)
转义符 作用
\U 后面的字符全部转为大写,直到\E结束
\L 后面的字符全部转为小写,直到\E结束
\u 后面的第一个字符转为大写
\l 后面的第一个字符转为小写
示例:

sed 's/^[a-z]/\u&/g' file.txt  # 每行首字母大写
sed 's/[A-Z]/\l&/g' file.txt   # 所有大写字母转为小写
sed 's/\(.*\):\(.*\)/\U\1\E:\2/g' file.txt  # 冒号前的内容全部大写

5.2 删除命令 d

语法:地址d,删除匹配地址的行


sed '2d' file.txt              # 删除第2行
sed '2,5d' file.txt            # 删除2-5行
sed '/^$/d' file.txt           # 删除纯空行
sed '/^[[:space:]]*$/d' file.txt  # 删除含空格/制表符的空行
sed '/^#/d' file.txt           # 删除#开头的注释行
sed '/error/d' file.txt        # 删除包含error的行
sed '1,/^END$/!d' file.txt     # 只保留1行到匹配END的行,其余全部删除

5.3 打印命令 p

语法:地址p,打印匹配地址的行,几乎都配合-n使用(避免重复输出)


sed -n '2p' file.txt           # 仅打印第2行
sed -n '2,5p' file.txt         # 打印2-5行
sed -n '/error/p' file.txt     # 打印包含error的行(等效grep error)
sed -n '1~2p' file.txt         # 打印奇数行
sed -n '/start/,/end/p' file.txt  # 打印start到end之间的行
sed -n 'p;n' file.txt          # 打印奇数行,n读取下一行
sed -n 'n;p' file.txt          # 打印偶数行

5.4 追加/插入/整行替换命令

  • a\:在匹配行之后追加文本

  • i\:在匹配行之前插入文本

  • c\:将匹配行整行替换为指定文本


# 追加:第2行后追加"new line"
sed '2a\new line' file.txt
# 插入:匹配error的行前插入"=====ERROR START====="
sed '/error/i\=====ERROR START=====' file.txt
# 整行替换:第5行替换为"replaced line"
sed '5c\replaced line' file.txt
# 范围替换:2-4行全部替换为"=====CUT====="
sed '2,4c\=====CUT=====' file.txt

5.5 其他常用基础命令

命令 核心作用 示例
y 按字符一一对应转换,类似tr命令 sed 'y/abc/ABC/' file.txt 小写a/b/c转大写
r 文件名 读取文件内容,追加到匹配行之后 sed '$r footer.txt' file.txt 末尾追加文件内容
w 文件名 将匹配行写入指定文件 sed -n '/error/w error.log' file.txt 提取错误日志
= 打印匹配行的行号 sed -n '/error/=' file.txt 打印含error行的行号
q 匹配到指定行后直接退出sed sed '5q' file.txt 打印前5行后退出(等效head -5)
n 读取下一行到模式空间,覆盖当前内容 sed '/error/{n;d}' file.txt 删除匹配行的下一行

六、sed正则表达式规范

sed默认使用基础正则表达式(BRE),加-E/-r启用扩展正则表达式(ERE),核心元字符差异如下:

元字符 含义 BRE是否需要转义 ERE是否需要转义
^ 行开头锚点
$ 行结尾锚点
. 匹配任意单个字符
* 匹配前一个字符0次或多次
+ 匹配前一个字符1次或多次 是(+)
? 匹配前一个字符0次或1次 是(?)
{n,m} 匹配前一个字符n到m次 是({n,m})
() 分组,用于反向引用 是(())
` ` 或逻辑匹配 是(`
补充跨平台兼容规范:
  • POSIX预定义字符类(全平台兼容):[[:digit:]](数字)、[[:alpha:]](字母)、[[:space:]](空白字符)、[[:lower:]](小写)、[[:upper:]](大写)

  • 单词边界:GNU sed支持\b,BSD sed(macOS)需用[[:<:]](单词开头)和[[:>:]](单词结尾),跨平台优先用POSIX标准写法。

七、高级用法:模式空间+保持空间交互

sed的高级多行处理能力,核心是模式空间与保持空间的数据交互,核心交互命令如下:

命令 核心作用
h 把模式空间内容覆盖写入保持空间
H 把模式空间内容追加到保持空间(加换行符)
g 把保持空间内容覆盖写入模式空间
G 把保持空间内容追加到模式空间(加换行符)
x 交换模式空间和保持空间的内容
N 读取下一行,追加到模式空间(用换行符分隔,合并多行)
D 删除模式空间中第一个换行符之前的内容,剩余内容继续执行命令
P 打印模式空间中第一个换行符之前的内容

经典高级用法示例

  1. 合并相邻两行(两行合并为一行,空格分隔)

sed 'N;s/\n/ /' file.txt
  1. 文本行反转(等效tac命令)

sed '1!G;h;$!d' file.txt
# 解析:
# 1!G:除了第一行,都把保持空间内容追加到模式空间
# h:把模式空间内容覆盖到保持空间
# $!d:除了最后一行,都删除模式空间内容,不输出
  1. 打印匹配内容的前后行

sed -n '/error/{N;p}' file.txt   # 打印匹配行和下一行
sed -n '/error/{x;p;x;p}' file.txt  # 打印匹配行和上一行
  1. 给所有行加上行号

sed = file.txt | sed 'N;s/\n/ /'

八、生产级实战案例

  1. 批量修改配置文件(安全备份+替换)

# 替换配置文件中port=8080为port=9090,先备份为.ini.bak
sed -i.bak 's/^port=8080$/port=9090/g' app.ini
  1. 清理配置文件(删除空行+注释行)

sed -i.bak -e '/^#/d' -e '/^[[:space:]]*$/d' nginx.conf
  1. 批量重命名文件(配合xargs)

# 将所有.txt文件改为.md文件
ls *.txt | sed 's/\(.*\)\.txt/mv & \1.md/' | bash
  1. 提取HTML中的链接

sed -n 's/.*href="\([^"]*\)".*/\1/p' index.html
  1. 批量给行首尾加标签包裹

# 给每行内容加上<p>和</p>包裹
sed 's/^.*$/<p>&<\/p>/g' index.html

九、避坑指南与最佳实践

9.1 新手致命坑

  1. -i直接修改原文件无撤回:执行前必须先用不带-i的命令测试输出,确认无误再加-i,优先用-i.bak备份

  2. 替换不加g只改第一个匹配:默认s/old/new/仅替换每行第一个匹配项,全局替换必须加g

  3. 正则元字符未转义:匹配. * ? ^ $ /等字面量时,必须加\转义,或换用自定义分隔符

  4. 二进制文件修改:sed仅适用于纯文本文件,修改压缩包、图片、可执行文件会直接损坏文件

9.2 跨平台兼容性坑(GNU sed vs BSD sed)

特性 GNU sed(Linux) BSD sed(macOS/FreeBSD) 兼容写法
-i无备份 sed -i 's/old/new/g' file 必须指定后缀,无备份写sed -i '' 's/old/new/g' file -i.bak生成备份,兼容所有平台
单词边界 支持\b 不支持\b,需用[[:<:]][[:>:]] 用POSIX标准[[:<:]]word[[:>:]]
扩展正则 -r/-E等效 优先用-E 统一用-E启用扩展正则

9.3 性能优化最佳实践

  1. 避免循环调用sed:批量处理多个文件,直接sed '命令' *.txt,不要在for循环中逐个调用sed

  2. 合并多个命令:多个操作合并为一个sed命令,用-e{}组合,避免多次读取文件

  3. 提前退出:处理到指定行即可退出,比如打印前10行用sed '10q' file,比sed -n '1,10p' file效率更高

  4. 大文件加速:用LC_ALL=C sed '命令' file关闭本地化校验,大幅提升正则匹配速度

十、高频命令速查表

场景 命令
全局文本替换 sed 's/old/new/g' file
仅打印匹配行 sed -n '/pattern/p' file
删除纯空行 sed '/^$/d' file
删除注释行+空行 sed -e '/^#/d' -e '/^[[:space:]]*$/d' file
打印前N行 sed 'Nq' file
行尾追加内容 sed 's/$/追加内容/g' file
行首添加内容 sed 's/^/添加内容/g' file
反转行顺序 sed '1!G;h;$!d' file
打印文件最后一行 sed -n '$p' file

(注:文档部分内容可能由 AI 生成)