sed 命令使用详细总结
sed 命令使用详细总结
sed(Stream Editor)是Linux/Unix生态下的非交互式流编辑器,是文本处理三剑客(grep/sed/awk)核心成员,以逐行流式处理为核心,无需打开文件即可完成批量文本修改、过滤、提取等操作,是自动化脚本、运维文本处理的核心工具。
一、核心执行原理(必懂)
sed的处理逻辑全程围绕两个核心缓冲区展开,理解这一点就能彻底搞懂sed的工作模式:
-
模式空间(Pattern Space):主处理缓冲区,逐行读取文本后载入此处,所有编辑命令默认仅作用于此,处理完一轮即清空
-
保持空间(Hold Space):辅助暂存缓冲区,编辑命令无法直接作用,仅用于和模式空间交互数据,用于多行处理等高级场景
核心执行流程:
-
读取一行文本,去除换行符后载入模式空间
-
按「地址定位规则」匹配当前行,匹配成功则执行对应的编辑命令
-
命令执行完成后,默认将模式空间内容(恢复换行符)输出到标准输出
-
清空模式空间,读取下一行,循环直至文件结束
关键提示: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 |
替换进阶用法
- 自定义分隔符(处理路径/URL)
sed 's#/home/user#/opt/data#g' file.txt # 用#替代/,避免路径转义&引用匹配到的完整内容
sed 's/[0-9]\+/(&)/g' file.txt # 给所有数字加上括号,&代表匹配到的数字
sed 's/^.*$/【&】/g' file.txt # 给每行内容加上【】包裹- 分组与反向引用
基础正则(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- 大小写转换(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.txt5.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 |
打印模式空间中第一个换行符之前的内容 |
经典高级用法示例
- 合并相邻两行(两行合并为一行,空格分隔)
sed 'N;s/\n/ /' file.txt- 文本行反转(等效tac命令)
sed '1!G;h;$!d' file.txt
# 解析:
# 1!G:除了第一行,都把保持空间内容追加到模式空间
# h:把模式空间内容覆盖到保持空间
# $!d:除了最后一行,都删除模式空间内容,不输出- 打印匹配内容的前后行
sed -n '/error/{N;p}' file.txt # 打印匹配行和下一行
sed -n '/error/{x;p;x;p}' file.txt # 打印匹配行和上一行- 给所有行加上行号
sed = file.txt | sed 'N;s/\n/ /'八、生产级实战案例
- 批量修改配置文件(安全备份+替换)
# 替换配置文件中port=8080为port=9090,先备份为.ini.bak
sed -i.bak 's/^port=8080$/port=9090/g' app.ini- 清理配置文件(删除空行+注释行)
sed -i.bak -e '/^#/d' -e '/^[[:space:]]*$/d' nginx.conf- 批量重命名文件(配合xargs)
# 将所有.txt文件改为.md文件
ls *.txt | sed 's/\(.*\)\.txt/mv & \1.md/' | bash- 提取HTML中的链接
sed -n 's/.*href="\([^"]*\)".*/\1/p' index.html- 批量给行首尾加标签包裹
# 给每行内容加上<p>和</p>包裹
sed 's/^.*$/<p>&<\/p>/g' index.html九、避坑指南与最佳实践
9.1 新手致命坑
-
-i直接修改原文件无撤回:执行前必须先用不带-i的命令测试输出,确认无误再加-i,优先用-i.bak备份 -
替换不加
g只改第一个匹配:默认s/old/new/仅替换每行第一个匹配项,全局替换必须加g -
正则元字符未转义:匹配
.*?^$/等字面量时,必须加\转义,或换用自定义分隔符 -
二进制文件修改: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 性能优化最佳实践
-
避免循环调用sed:批量处理多个文件,直接
sed '命令' *.txt,不要在for循环中逐个调用sed -
合并多个命令:多个操作合并为一个sed命令,用
-e或{}组合,避免多次读取文件 -
提前退出:处理到指定行即可退出,比如打印前10行用
sed '10q' file,比sed -n '1,10p' file效率更高 -
大文件加速:用
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 生成)