超详细!SED流编辑器从入门到精通
在文本处理的世界里,SED 流编辑器宛如一把瑞士军刀,功能强大且实用。无论是处理海量数据文件,还是批量修改配置文件,SED 都能展现出其独特的魅力。今天,就让我们一同深入探索 SED 的奇妙世界,掌握其基础知识和实用技巧,让文本处理变得轻松自如。
一、SED:文本处理的神器
1. SED 是什么
SED(Stream Editor)是一款流编辑工具,专门用于对文本进行过滤与替换工作。它能够以一种高效且灵活的方式处理文本,尤其适用于大规模文本文件的操作。例如,当你面对几十个配置文件需要进行统一修改时,SED 就能发挥巨大作用,让你在短时间内完成任务。
2. SED 的工作流程
- 读取文件:SED 通过文件或管道读取文件内容,每次仅读取一行。这使得它在处理大数据文件时不会占用过多内存,保证了处理效率。
- 模式空间操作:读取的内容会被复制到缓冲区,也就是模式空间(Pattern Space)。在这里,SED 根据指令对内容进行处理。
- 输出结果:处理后的结果默认输出至标准输出(即屏幕)。如果需要,也可以将结果重定向保存到文件中。
以下是 SED 工作流程的示意图:
输入
------------------------------------------------
|
|
v
读取一行内容,并复制到模式空间 <------------ sed 指令
|
|
v
------------------------------------------------
输出经过处理后的内容二、SED 基本语法:开启文本处理之旅
1. 基本语法格式
sed [Options]... [script] [inputfile...]其中:
Options:SED 程序本身的选项,用于控制 SED 的行为。script:脚本指令,用于指定对文件内容的操作。inputfile:输入文件。如果没有指定,则 SED 默认对标准输入进行处理(如键盘输入或管道)。
2. 常用选项解析
| 选项 | 说明 |
|---|---|
--version | 显示 SED 版本。 |
--help | 显示帮助文档。 |
-n, --quiet, --silent | 静默输出,屏蔽 SED 程序自动打印模式空间内容的功能。 |
-e script | 允许多个脚本指令被执行。 |
-f script-file | 从文件中读取脚本指令,方便编写自动脚本程序。 |
-i, --in-place | 直接修改源文件,处理后的内容将覆盖源文件内容(谨慎使用)。 |
-l N | 指定 l 指令输出的行长度,l 指令用于输出非打印字符。 |
--posix | 禁用 GNU SED 扩展功能。 |
-r, --regexp-extended | 在脚本指令中使用扩展正则表达式。 |
-s, --separate | 控制 SED 对多个文件名的处理方式。 |
-u, --unbuffered | 最低限度缓存输入与输出。 |
3. 简单案例演示
假设我们有一个名为 test.txt 的文件,内容如下:
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
IPADDR=192.168.0.1
NETMASK=255.255.255.0
GATEWAY=192.168.0.2543.1 追加与插入
在第二行后添加
TYPE=Ethernet:sed '2a TYPE=Ethernet' test.txt在第三行前添加
TYPE=Ethernet:sed '3i TYPE=Ethernet' test.txt
3.2 替换
将文件中所有的 yes 替换为 no:
sed 's/yes/no/g' test.txt3.3 删除
删除第 3 至 4 行的内容:
sed '3,4d' test.txt3.4 使用正则表达式定位操作行
匹配到包含
ONBOOT的行,并在其后添加TYPE=Ethernet:sed '/ONBOOT/a TYPE=Ethernet' test.txt匹配以
GATEWAY开始的行,并删除该行:sed '/^GATEWAY/d' test.txt
3.5 从脚本文件中读取指令
创建一个名为 sed.sh 的脚本文件,内容如下:
/^$/d这条指令的作用是删除空白行。然后执行:
sed -f sed.sh test.txt3.6 执行多个指令的方法
使用分号隔开指令:
sed 's/yes/no/;s/static/dhcp/' test.txt使用
-e选项:sed -e 's/yes/no/' -e 's/static/dhcp/' test.txt利用分行指令:
sed ' s/yes/no/ s/static/dhcp/' test.txt
三、正则表达式:精准定位文本
1. 确定操作地址
行号指定:
number:指定输入文件的唯一行号,如2d表示删除第二行。first~step:以first开始,操作步长为step,如1~2表示打印文件的奇数行。$:匹配文件的最后一行。
正则表达式匹配:
/regexp/:通过正则表达式匹配操作地址,例如/ONBOOT/匹配包含ONBOOT的行。\cregexpc:匹配扩展正则表达式,c字符可以使用任意字符替代。
范围指定:
addr1,addr2:匹配从操作地址1到操作地址2的所有行,如2,8d删除 2 至 8 中间的所有行。addr1,+N:匹配地址1以及后面的N行内容。
2. 正则表达式概述
字符匹配:
char:字符本身匹配字符本身,如/abc/定位包含abc的行。
数量限定符:
*:匹配前面表达式出现了 0 或若干次,如/a*/可以找到a、aa、aaa等。\+(扩展正则表达式):匹配前面表达式的 1 次或多次。\?(扩展正则表达式):匹配前面表达式的 0 次或 1 次。\{i\}:匹配前面表达式的i次(i为整数),如a\{3\}找到aaa。\{i,j\}:匹配前面表达式的i到j次,如a\{1,2\}找到a或aa。\{i,\}:匹配前面表达式至少i次。
分组与引用:
():将内的模式存储在保留空间,最多可存储 9 个独立子模式,可通过转义\1至\9重复保留空间的内容。
其他元字符:
.(点):匹配任意字符。^:匹配行的开始,如^test匹配所有以test开始的行。$:匹配行的结尾,如test$匹配所有以test结尾的行。[]:匹配括号中的任意单个字符,如a[nt]匹配an或at。[^]:匹配不包含在[]中的字符,如[^a-z]匹配除a-z以外的字符。\n:匹配换行符。\char:转义特殊字符,如\*匹配字面意义上的星号。
四、SED 脚本指令:实现多样化操作
1. 注释(#)
注释行以 # 开始。如果 # 后面的字符为 n,则屏蔽 SED 程序的自动输出功能,等同于命令选项 -n。
2. 替换(s)
基本格式:
[address]s/pattern/replacement/flags其中,
address为操作地址,s为替换指令,/pattern/匹配要替换的内容,/replacement/为替换的内容。flags可以是:n(1 至 512 之间的数字):表示对模式空间中指定模式的第n次出现进行替换。g:对模式空间的匹配进行全局更改,没有g则仅第一次匹配被替换。p:打印模式空间的内容。w file:将模式空间的内容写到文件file中。
示例:
假设有一个名为test.txt的文件,内容如下:<html> <title>First Web</title> <body>Hello the World! <body> </html>目标:将样本文件中的第二个
<body>替换为</body>。
编写sed.sh脚本如下:/body/{ s//\/body/2 }执行
sed程序:sed -f sed.sh test.txt结果为:
<html> <title>First Web</title> <body>Hello the World!</body> </html>
3. 删除(d)
删除指令删除匹配的行,且会改变 SED 脚本中命令的执行顺序。因为匹配的行被删除后,模式空间变为“空”,SED 脚本后续命令不再执行,而是读取新的输入行,从头开始执行命令。
4. 追加(a)
在匹配行后追加内容。例如,对于文件 test.txt:
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
NETMASK=255.255.255.0
GATEWAY=192.168.0.254执行 sed '/static/a IPADDR=192.168.0.1' test.txt,会在包含 static 的行后添加一行 IPADDR=192.168.0.1。
5. 插入(i)
在匹配行前插入内容。如 sed '/NETMASK/i IPADDR=192.168.0.1' test.txt,会在包含 NETMASK 的行前添加一行 IPADDR=192.168.0.1。
6. 更改(c)
更改匹配行的内容。例如,sed '/ONBOOT/c ONBOOT=yes' test.txt 会将包含 ONBOOT 的行(整行)替换为 ONBOOT=yes。
7. 列印(l)
显示模式空间中的内容,显示非打印字符,一般与 -n 一起使用,否则会输出两次。例如,sed -n '1,2l' test.txt 会显示文件的第一、二行内容及换行符(以 $ 表示)。
8. 转换(y)
按字符进行转换。例如,对于文件 test.txt:
DEVICE=eth0
ONBOOT=yes
BOOTPROTO=static
netmask=255.255.255.0
GATEWAY=192.168.0.254编写 sed.sh 脚本:
/.*/{
/netmask/y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
}执行 sed -f sed.sh test.txt,会将 netmask 中的小写字母转换为大写字母。
9. 打印(p)
作用类似于 l,但不显示非显示字符,一般与 -n 配合使用。如 sed -n '1,2p' test.txt 仅显示第一、二行内容。
10. 读写文件(r, w)
读取文件(r):
格式:[line-address]r file。
例如,有name.txt和mail.txt两个文件:name.txt内容:Jacob Tom Jerrymail.txt内容:jacob@gmail.com tom@gmail.com jerry@gmail.com编写
sed.sh脚本:/.*/{ $r mail.txt }执行
sed -f sed.sh name.txt,会在name.txt文件末尾添加mail.txt的内容。- 写入文件(w):
格式:[address]w file,可以将指定行的内容写入到文件中。
11. 退出(q)
匹配地址后退出 SED 脚本。例如,sed '10q' test.txt 会打印文件前 10 行内容后退出。
12. 下一步(n)
[address]n,输出模式空间中的内容,然后读取输入的下一行。例如,对于文件 name.txt:
Jacob
Tom
Jerry编写 sed.sh 脚本:
/.*/{
n
/.*/d
}执行 sed -f sed.sh name.txt,会删除偶数行,结果为:
Jacob
Jerry13. Next(N)
多行 Next(N) 命令通过读取新的输入行,并将它添加到模式空间的现有内容之后,来创建多行模式空间。模式空间的最初内容与新的输入行之间用换行符分隔。例如,对于文件 test.txt:
111
222
222
333编写 sed.sh 脚本:
#n
/222/{
N
l
}执行 sed -f sed.sh test.txt,结果如下:
222\n22214. Print(P)
多行打印(P)与打印(p)稍有不同,该命令仅输出多行模式空间中的第一部分,直到第一个插入的 \n 换行符为止。例如,对于文件 test.txt:
111
222
333
444
555
666编写不同的 sed.sh 脚本并执行,结果如下:
脚本 1:
/.*/{ N }结果:
111 222 333 444 555 666脚本 2:
/.*/{ N l }结果:
111\n222$ 111 222\n333$ 222 333\n444$ 333 444\n555$ 444 555\n666$ 555 666脚本 3:
/.*/{ N P }结果:
111 111 222 222 333 333 444 444 555 555 666 666脚本 4:
/.*/{ N p }结果:
111 222 111 222 333 444 333 444 555 666 555 666
15. Delete(D)
删除命令(D)删除模式空间中直到第一个插入的换行符(\n)前的这部分内容,它不会读入新的输入行,并返回 SED 脚本的顶端,使得剩余指令继续应用于模式空间中剩余的内容。
16. Hold(h, H),Get(g, G)
模式空间用于存放当前输入行,还有一个保持空间(Hold Space)。可以使用以下命令在两者之间移动数据:
Hold(h|H):将模式空间的内容复制或追加到保持空间。Get(g|G):将保持空间的内容复制或追加到模式空间。Exchange(x):交换保持空间与模式空间的内容。
例如,对于文件 test.txt:
1
2
11
22
111
222编写 sed.sh 脚本:
/1/{
h
d
}
/2/{
G
}执行 sed -f sed.sh test.txt,结果为:
2
1
22
11
222
11117. Branch & Test(b, t)
分支(b)和测试(t)命令用于控制 SED 脚本的执行流程。分支命令是无条件转移,测试命令用于有条件转移(只有当替换命令改变当前行成功时才会执行)。标签是任意不多于 7 个字符的序列,以冒号开始,如 :mylable。在分支或测试命令后指定标签名即可实现流程跳转。
说明:本文基于 GNU SED 常见用法编写,不同操作系统(如 macOS 默认的 BSD SED)在某些选项和正则表达式支持上可能存在差异,使用时请注意版本兼容性。
版权声明:本文为原创文章,版权归 戴老师的博客 所有,转载请联系博主获得授权。
本文地址:https://1diff.fun/archives/chao-xiang-xi-sed-liu-bian-ji-qi-cong-ru-men-dao-jing-tong.html
如果对本文有什么问题或疑问都可以在评论区留言,我看到后会尽量解答。