sed 命令使用手册
sed 命令使用手册
一、sed 工具定位与背景
1. sed 核心定义
sed
(全称stream editor
,流编辑器)是 Linux/Unix 系统中非交互式文本处理工具,核心能力是按规则批量处理文本流(文件、管道输出等),无需手动编辑文件,擅长 “替换、删除、插入” 等操作。
2. 文本处理工具对比
sed
与grep
、awk
并称为 “Linux 文本三剑客”,三者定位互补,覆盖不同文本处理场景:
工具 | 核心优势 | 典型用途 |
---|---|---|
grep | 擅长过滤文本 | 按关键词 / 正则筛选行、统计匹配次数 |
sed | 擅长修改文本 | 批量替换字符、删除指定行、插入内容 |
awk | 擅长格式化输出 | 按列提取数据、计算统计值、生成结构化报告 |
此外,sed
与awk
也被称为 “两大王牌文字处理器”,区别在于:
sed
:侧重点是替换与行级修改(以行为单位处理)。awk
:侧重点是分割与字段级处理(以列 / 字段为单位处理)。
3. sed 历史背景
- 诞生时间:1973-1974 年(“70 后” 工具)。
- 诞生地:贝尔实验室。
- 开发者:麦克马洪(McMahon),初衷是改进更早的行编辑器
ed
,最终发展为sed
。
二、sed 工作流程与核心概念
sed
的工作流程遵循 “逐行处理、循环执行” 的逻辑,依赖两个核心内存空间,理解这一流程是掌握sed
的关键。
1. 核心工作流程
sed
的处理流程可概括为 “读取→执行→显示” 的循环,直到输入流(文件 / 管道)处理完毕:
- 读取行:从输入流中读取一行文本,存入内存中的
pattern space
(模式空间),同时更新行计数器(记录当前行号)。 - 执行命令:按用户指定的
sed
命令,对pattern space
中的行进行处理(如替换、删除、插入)。默认处理所有行,可通过 “行号 / 模式” 指定目标行。 - 显示结果:将
pattern space
中处理后的内容输出到输出流(屏幕、文件等),然后清空pattern space
,准备处理下一行。 - 循环:重复 “读取→执行→显示”,直到输入流所有行处理完成。
2. 两个核心内存空间
sed
依赖两个内存空间实现数据暂存与交互,二者特性差异如下:
空间名称 | 作用 | 生命周期 | 核心特点 |
---|---|---|---|
pattern space (模式空间) | 临时存储当前处理的行,所有sed 命令均作用于此空间 | 每处理一行后清空 | 相当于 “流水线”,实时处理当前行 |
hold space (保持空间) | 长期存储处理后的数据,用于后续行的调用 | 全程不自动清空,需手动操作 | 相当于 “仓库”,暂存数据供跨行使用 |
3. 关键注意事项
- 默认不修改源文件:
sed
仅处理pattern space
中的数据,输出结果默认打印到屏幕,源文件内容不变(需用-i
选项实现 “原地修改”)。 - 无输入文件时读标准输入:若未指定
[input-file]
,sed
默认从标准输入(如键盘输入、管道输出)读取数据。 - 支持行范围筛选:默认处理所有行,可通过 “行号” 或 “模式匹配” 指定仅处理部分行。
三、sed 基础语法与常用选项
sed
的语法结构清晰,核心由 “选项、命令、输入文件” 三部分构成,以下是基础语法与高频选项解析。
1. 基础语法格式
[root@server ~ 23:34:35]# cp -a /etc/nginx/nginx.conf test.txt# 示例:用-n选项关闭自动打印,1p命令打印test.txt的第1行
[root@server ~ 23:35:20]# sed -n '1p' test.txt
For more information on configuration, see:
2. 核心选项详解(附代码案例与注释)
sed
的选项用于改变工作流程(如原地修改、关闭自动打印、使用扩展正则等),以下是高频选项及实操案例:
选项 | 英文全称 / 含义 | 作用说明 | 实操案例(带注释) | |
---|---|---|---|---|
-n | --quiet/--silent | 关闭pattern space 的 “自动打印”,仅显示sed 命令指定的输出(如p 命令) | bash # 案例1:不使用-n,默认自动打印所有行(与cat test.txt效果一致) sed '' test.txt # 案例2:使用-n+1p,仅打印第1行(无多余输出) sed -n '1p' test.txt | |
-e | --expression=script | 指定多个sed 命令(用分号分隔或多次用-e ) | bash # 案例:删除第1行并替换“root”为“tank” sed -e '1d' -e 's/root/tank/g' test.txt # 等价于:sed '1d;s/root/tank/g' test.txt(分号分隔多命令) | |
-f | --file=script-file | 从指定文件中读取sed 命令(适合命令较多的场景,每命令占一行) | bash # 步骤1:创建命令文件scripts(每行一个命令) echo -e "1d\n2d\n5d" > scripts # 步骤2:用-f读取scripts,处理data.txt sed -f scripts data.txt | |
-i | --in-place[=SUFFIX] | 原地修改输入文件(源文件直接变更),可选SUFFIX 备份源文件(如-i.bak ) | bash # 案例1:直接原地修改(无备份) sed -i 's/root/tank/g' test.txt # 案例2:修改并备份源文件(备份为test.txt.bak) sed -i.bak 's/root/tank/g' test.txt | |
-r | --regexp-extended | 使用扩展正则表达式(无需对{n} 、` | ` 等符号转义,简化复杂匹配) | bash # 案例1:不用-r,需对()转义(匹配“zhangy”并替换) sed -ne '2,8s/\(zhangy\)/zhangying/gp' test.txt # 案例2:用-r,无需转义(效果同上) sed -nre '2,8s/(zhangy)/zhangying/gp' test.txt |
-b | --binary | 以二进制模式处理文件(兼容 Windows/DOS 文件,不特殊处理 CR+LF 换行) | bash # 案例:处理Windows格式的文件(避免换行符问题) sed -b 's/\r//g' windows.txt # 删除\r,将CR+LF转为LF |
四、sed 核心命令详解(附代码案例)
sed
的命令是文本处理的核心,按功能可分为 “打印、替换、删除、插入、更改” 等类别,以下是高频命令及实操案例(所有案例基于示例文件test
,内容见下文)。
先定义示例文件test
为统一案例环境,先创建test
文件,后续案例均基于此文件:
# 创建test文件,包含5行内容
[root@server ~ 23:35:24]# cat <<'EOF' > ~/test
> This is 1
> This is 2
> This is 3
> This is 4
> This is 5
> EOF
1. 打印命令(p
/P
):输出指定行
p
命令用于打印pattern space
中的内容,P
命令仅打印pattern space
的第一行(常用于多行模式),需结合-n
选项避免重复输出。
实操案例
# 案例1:打印所有行(等价于sed '' test或cat test)
[root@server ~ 23:36:48]# sed -n 'p' test
This is 1
This is 2
This is 3
This is 4
This is 5# 案例2:打印第3行(单个行号address)
[root@server ~ 23:37:50]# sed -n '3p' test
This is 3# 案例3:打印第2~4行(行号范围address1,address2)
[root@server ~ 23:37:58]# sed -n '2,4p' test
This is 2
This is 3
This is 4# 案例4:打印第3行到最后一行($表示最后一行)
[root@server ~ 23:38:05]# sed -n '3,$p' test
This is 3
This is 4
This is 5# 案例5:打印第2行及后续2行(+N表示“从address1开始,共N+1行”)
[root@server ~ 23:38:11]# sed -n '2,+2p' test
This is 2
This is 3
This is 4# 案例6:隔行打印(1~2p表示“从第1行开始,每2行打印一次”)
[root@server ~ 23:38:19]# sed -n '1~2p' test
This is 1
This is 3
This is 5# 案例7:模式匹配打印(打印含“is 3”的行)
[root@server ~ 23:38:26]# sed -n '/is 3/p' test
This is 3
2. 替换命令(s
):批量替换字符
s
命令是sed
最常用的命令,用于 “查找并替换” 文本,支持正则表达式,核心语法为[address]s/源字符串/目标字符串/选项
。
实操案例
# 先准备替换用的示例文件test1.txt(3行重复的“my”)
[root@server ~ 23:38:32]# cat <<'EOF' > ~/test1.txt
> my my my my my
> my my my my my
> my my my my my
> EOF#全局替换(将所有“my”改为“your”,g表示global全局)
[root@server ~ 23:40:29]# sed 's/my/your/g' test1.txt
your your your your your
your your your your your
your your your your your# 模式匹配替换(仅替换含“root”的行中的“bash”为“sh”)
[root@server ~ 23:40:36]# sed -n '/root/s/bash/sh/gp' /etc/passwd
root:x:0:0:root:/root:/bin/sh
3. 删除命令(d
/D
):删除指定行
d
命令删除pattern space
中的所有行,D
命令仅删除pattern space
的第一行(常用于多行模式),删除后的数据不输出,源文件默认不变(需-i
原地删除)。
实操案例
#删除第1~2行
[root@server ~ 23:41:22]# sed '1,2d' test
This is 3
This is 4
This is 5#删除第4行及以后的行
[root@server ~ 23:43:27]# sed '4,$d' test
This is 1
This is 2
This is 3#删除含“false”或“bash”的行(正则匹配,\转义|表示“或”)
[root@server ~ 23:43:35]# sed '/\(false\|bash\)/d' /etc/passwd#模式范围删除(删除“root”行到“test”行之间的所有行)
sed '/root/,/test/d' /etc/passwd#D命令删除偶数行(利用N读取下一行,D删除第一行)
[root@server ~ 23:46:44]# echo -e "This is 1\nThis is 2\nThis is 3\nThis is 4\nThis is 5" | sed 'n;D'
This is 1
This is 3
This is 5
4. 插入命令(a
/i
):在指定行前后插入内容
a
(append)命令在匹配行下方插入新内容,i
(insert)命令在匹配行上方插入新内容,插入的内容需用单引号包裹,支持换行(用\n
)。
实操案例
#案例1:a命令(在root行下方插入“=====分隔符=====”)
[root@server ~ 23:48:20]# sed '/root/a =====分隔符=====' /etc/passwd
root:x:0:0:root:/root:/bin/bash
=====分隔符=====
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin#案例2:i命令(在root行上方插入“=====头部=====”)
[root@server ~ 23:49:47]# sed '/root/i =====头部=====' /etc/passwd
=====头部=====
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin# 案例3:插入多行内容(用\n换行,插入2行文本)
[root@server ~ 23:50:33]# sed '/root/a 第一行插入\n第二行 插入' /etc/passwd
root:x:0:0:root:/root:/bin/bash
第一行插入
第二行插入
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
5. 更改命令(c
):整行替换
c
(change)命令将匹配行的全部内容替换为指定字符串,区别于s
命令(仅替换部分字符),c
命令是 “整行覆盖”。
实操案例
# 案例1:将root行整行替换为“hello, this is new line”
[root@server ~ 23:51:23]# sed '/root/c hello, this is new line' /etc/passwd
hello, this is new line
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin# 案例2:将第3行整行替换为“Third line is replaced”
[root@server ~ 23:52:24]# sed '3c Third line is replaced' test
This is 1
This is 2
Third line is replaced
This is 4
This is 5
6. 读写命令(r
/w
):文件交互
r
(read):从外部文件读取内容,插入到匹配行下方。w
(write):将pattern space
中匹配的行,写入到外部文件(覆盖原有内容)。
实操案例
# 步骤1:创建用于读取的文件test2.txt(含分隔符)
[root@server ~ 23:53:12]# echo -e "++++++++++\n分隔符内容\n++++++++++" > ~/test2.txt
[root@server ~ 23:53:53]# cat ~/test2.txt
++++++++++
分隔符内容
++++++++++# 案例1:r命令(在root行下方插入test2.txt的内容)
[root@server ~ 23:54:08]# sed '/root/r test2.txt' /etc/passwd
root:x:0:0:root:/root:/bin/bash
++++++++++
分隔符内容
++++++++++
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin# 案例2:w命令(将含“root”的行写入test3.txt)
[root@server ~ 23:54:28]# sed -n '/root/w test3.txt' /etc/passwd
[root@server ~ 23:55:17]# cat test3.txt
root:x:0:0:root:/root:/bin/bash
operator:x:11:0:operator:/root:/sbin/nologin
五、sed 模式寻址(行号与模式匹配)
sed
支持通过 “行号” 或 “模式匹配” 指定处理的行(即 “寻址”),是精准处理文本的核心,以下是常见寻址方式及案例。
1. 行号寻址
通过具体行号或行号范围,指定处理目标,支持以下格式:
寻址格式 | 含义 | 案例(打印命令) |
---|---|---|
n | 第 n 行 | sed -n '3p' test (打印第 3 行) |
n,m | 第 n~m 行(含边界) | sed -n '2,4p' test (打印第 2~4 行) |
n,$ | 第 n 行到最后一行 | sed -n '3,$p' test (打印第 3~5 行) |
n,+m | 第 n 行及后续 m 行(共 m+1 行) | sed -n '2,+2p' test (打印第 2~4 行) |
n~m | 从第 n 行开始,每 m 行处理一次 | sed -n '1~2p' test (打印奇数行) |
2. 模式寻址
通过 “字符串匹配” 或 “正则表达式” 指定处理目标,格式为/pattern/
(pattern
为匹配规则),支持以下场景:
寻址格式 | 含义 | 案例(打印命令) |
---|---|---|
/pattern/ | 匹配含 pattern 的行 | sed -n '/is 3/p' test (打印含 “is 3” 的行) |
/pattern1/,/pattern2/ | 从匹配 pattern1 的行,到匹配 pattern2 的行 | sed -n '/root/,/bin/p' /etc/passwd (打印 root 行到 bin 行) |
/pattern/,n | 从匹配 pattern 的行,到第 n 行 | sed -n '/root/,3p' /etc/passwd (打印 root 行到第 3 行) |
n,/pattern/ | 从第 n 行,到匹配 pattern 的行 | sed -n '2,/bash/p' /etc/passwd (打印第 2 行到含 bash 的行) |
模式寻址案例
# 案例1:打印“root”开头的行到“mail”开头的行(正则^匹配行首)
[root@server ~ 23:55:29]# sed -n '/^root/,/^mail/p' /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin# 案例2:删除“false”结尾的行($匹配行尾)
[root@server ~ 23:56:35]# sed '/false$/d' /etc/passwd
六、sed 高级用法(hold space 操作与正则)
1. hold space 操作(g
/G
/h
/H
)
hold space
用于跨行数据交互,需通过g
/G
/h
/H
命令操作,四个命令的核心区别如下:
命令 | 作用 | 案例(带注释) |
---|---|---|
h | 清空hold space ,将pattern space 内容覆盖到hold space | bash # 将root行存入hold space,最后一行插入root行 sed -e '/root/h' -e '$G' /etc/passwd # 原理:h存root行到hold space,$G在最后一行后追加hold space内容 |
H | 不清空hold space ,将pattern space 内容追加到hold space (加 \n) | bash # 将前2行追加到hold space,最后一行插入 sed -e '1,2H' -e '$G' test # 输出:最后一行后追加第1~2行内容 |
g | 清空pattern space ,将hold space 内容覆盖到pattern space | bash # 用root行替换含“zhangy”的行 sed -e '/root/h' -e '/zhangy/g' /etc/passwd # 原理:h存root行,g用hold space内容覆盖zhangy行 |
G | 不清空pattern space ,将hold space 内容追加到pattern space (加 \n) | bash # 每一行后新增空行(利用G追加空的hold space) sed 'G' test # 输出:每行后多一行空行 |
2. 正则表达式在 sed 中的应用
sed
支持基础正则(默认)和扩展正则(-r
选项),常用正则符号及案例如下:
正则符号 | 含义 | 案例(替换命令) |
---|---|---|
^ | 匹配行首 | sed 's/^root/admin/' /etc/passwd (行首 root 改为 admin) |
$ | 匹配行尾 | sed 's/bash$/sh/' /etc/passwd (行尾 bash 改为 sh) |
. | 匹配任意单个非换行字符 | sed 's/is .$/is new/' test (“is” 后接任意字符的行尾改为 “is new”) |
* | 匹配前一个字符 0 次或多次 | sed 's/my*/your/' test1.txt (将 “my”“myy” 等改为 “your”) |
[] | 匹配括号内任意一个字符 | sed 's/[sS]ed/SED/' test (将 sed 或 Sed 改为 SED) |
\(\) | 捕获子串(基础正则需转义,扩展正则无需) | bash # 基础正则:捕获“ba”和“zhangy”,替换为“ba,haha” sed -nre 's/(ba).*(zhangy)/\1,haha/p' /etc/passwd # \1表示第一个捕获的子串(ba) |
& | 引用匹配到的全部内容 | sed 's/root/&_new/' /etc/passwd (在 root 后加_new,如 root→root_new) |
七、sed 退出状态码与总结
1. 退出状态码
sed
执行后的退出状态码(通过$?
查看)用于判断执行结果:
0
:执行成功(无论是否匹配到内容)。1
:执行失败(如命令语法错误、文件不存在)。2
: GNU sed 扩展状态码,通常不常用。
2. 核心总结
sed
作为 “流编辑器”,核心优势在于非交互式批量处理文本,关键要点如下:
-
工作流程:逐行读取→
pattern space
处理→输出→循环,默认不修改源文件。 -
核心命令
:
- 查:
p
(打印)、/pattern/
(模式匹配)。 - 改:
s
(替换)、c
(整行替换)、y
(大小写转换)。 - 删:
d
(删除行)、D
(删除首行)。 - 增:
a
(下方插入)、i
(上方插入)、r
(读文件插入)。
- 查:
-
常用选项:
-n
(关闭自动打印)、-i
(原地修改)、-r
(扩展正则)、-f
(读命令文件)。 -
高级技巧:利用
hold space
实现跨行数据交互,通过模式寻址精准定位目标行。
掌握sed
后,可结合grep
(筛选)和awk
(格式化),高效处理 Linux 系统中的各类文本任务(如日志分析、配置修改、数据提取)。