文章目录
一、sed是什么?
sed是一个流式文本编辑器,与交互式文本编辑器vim(vim篇在这里)和编程语言awk(awk篇在这里)都不同,sed是一个文本编辑器并且没有提供交互式编辑模式,在处理数据之前需要预先给出一组规则,sed会根据这组规则来编辑数据。
二、工作原理
sed编辑器处理一段文本时,首先会逐行进行处理,也就是说每次只读取一行内容;接着将读取的内容保存在一个临时缓存区中,这个缓存区叫做模式空间;然后根据预先提供的规则命令匹配并修改数据;再将该行输出到屏幕上并清空模式空间。sed处理完一行数据后,会继续处理下一行,不断重复这个过程,直到将文件中的所有数据处理完毕。
tips:sed把每一行都保存在模式空间中,对这个副本进行修改,所以默认不会修改或破坏源文件。
三、如何使用?
1、命令语法
sed [options] [script command] filenames
其中,script表示地址定界,command表示编辑命令。
2、常用选项
选 项 | 解 释 |
---|---|
-n | 不打印模式空间的内容至屏幕(关闭默认的完整输出) |
-e | 命令行模式上进行sed的动作编辑(多点编辑),即就是指定多个命令 |
-f<scriptfile> | 执行指定的sed脚本文件来处理文本 |
-r | 支持使用扩展正则表达式 |
-i[扩展名] | 直接修改源文件,如果指定扩展名则会备份源文件文件并修改源文件 |
3、地址定界
sed默认会处理文本的所有数据,如果想让命令只处理特定行或某些行,可以使用地址定界来进行指定。在这里你需要了解正则表达式!
地址类型 | 格 式 | 解 释 |
---|---|---|
不给地址 | 对全文进行处理 | |
单 地 址 | num | 指定的行,即第num行 |
^ | 第一行 | |
$ | 最后一行 | |
/pattern/(正则表达式) | 被此模式所能够匹配到的每一行 | |
地址范围 | num1,num2 | 从num1行开始,直到num2行结束 |
num1,+num2 | 从num1行开始,直到num1+num2行结束 | |
/pattern1/,/pattern2/ | 从匹配到pattern1的行开始,直到匹配到pattern2的行结束 | |
num,/pattern/ | 从num1行开始,直到匹配到pattern的行结束 | |
步 进 | first ~ step | 起始匹配行~步长 |
1~2 | 从第一行开始,以2为步长(奇数行) | |
2~2 | 从第二行开始,以2为步长(偶数行) |
4、编辑命令
命 令 | 解 释 |
---|---|
d | 删除模式空间匹配的行 |
p | 打印当前模式空间的内容,追加到默认输出之后 |
a \text | 在匹配到的行后面追加文本,支持使用\n实现多行追加 |
i \text | 在匹配到的行前面插入文本 |
c \text | 将匹配到的行替换为当前文本 |
w /PATH/TO/SOMEFILE | 保存模式空间匹配到的行至指定文件 |
r /PATH/FROM/SOMEFILE | 读取指定文件的内容至当前被模式匹配到的行后面 |
= | 为模式空间的行打印行号 |
! | 条件取反 |
s/要被替换的字符串/新的字符串/[flags] | 查找替换,其中分隔符可以自定义,比如s@@@、s###等; 其中,falgs为替换标志,如果不指定flags,则默认替换第一次匹配的内容; 常用的flags有: g:全局替换 w /PATH/TO/SOMEFILE:将替换成功的结果保存至指定文件中 p:打印替换成功的行 i:不区分大小写 e:拼接shell命令 n(数字):替换匹配到的行的第几个匹配到的内容 |
5、你一定需要几个实例!
- 这里先给出一段文本(testfile):
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
① 只打印包含north的行;
[root@localhost ~]# sed -n '/north/ p' testfile
northwest NW Charles Main 3.0 .98 3 34
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
② 删除第3行,其余行打印到屏幕;
[root@localhost ~]# sed -n '3 d;p' testfile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
③ 删除第3行到最后一行所有的行,将剩余部分打印到屏幕;
[root@localhost ~]# sed -n '3,$ d;p' testfile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
④ 将所有west替换成north,并打印替换后的文本到屏幕;
[root@localhost ~]# sed -n 's@west@north@g;p' testfile
northnorth NW Charles Main 3.0 .98 3 34
northern WE Sharon Gray 5.3 .97 5 23
southnorth SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
⑤ 将所有Hemenway替换成Jones,只打印改变了的行到屏幕;
[root@localhost ~]# sed -n 's@Hemenway@Jones@gp' testfile
southeast SE Patricia Jones 4.0 .7 4 17
⑥ 将包含north的行写入到文件newfile中;
[root@localhost ~]# sed -n '/north/ w newfile' testfile
[root@localhost ~]# cat newfile
northwest NW Charles Main 3.0 .98 3 34
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
⑦ 将文件newfile中的内容插入到最后一行后面;
[root@localhost ~]# sed '$ r newfile' testfile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
northwest NW Charles Main 3.0 .98 3 34
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
⑧ 在包含north的行后添加“lalalalala”;
[root@localhost ~]# sed '/\<north\>/ a lalalalala' testfile
western WE Sharon Gray 5.3 .97 5 23
southwest SW Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
southeast SE Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
lalalalala
central CT Ann Stephens 5.7 .94 5 13
⑨ 将字段SW和SE的行替换为"---“并将”@@@"添加到该行上面”;
#执行多个编辑命令,可以使用{}来组合命令,命令之间使用;隔开
#匹配多个目标并执行不同编辑命令,可以使用-e选项
[root@localhost ~]# sed -e '{s/SW/---/g;s/SE/---/g}' -e '/---/ i @@@' testfile
northwest NW Charles Main 3.0 .98 3 34
western WE Sharon Gray 5.3 .97 5 23
@@@
southwest --- Lewis Dalsass 2.7 .8 2 18
southern SO Suan Chin 5.1 .95 4 15
@@@
southeast --- Patricia Hemenway 4.0 .7 4 17
eastern EA TB Savage 4.4 .84 5 20
northeast NE AM Main Jr. 5.1 .94 3 13
north NO Margot Weber 4.5 .89 5 9
central CT Ann Stephens 5.7 .94 5 13
四、sed高级用法
之前讲到的sed用法仅局限于单行模式,也就是说当匹配的内容处在两行时就会出现问题;再就是模式空间无法保存被自己处理的行,因此sed又引入另一个缓存空间:保持空间。在这里我们主要围绕这两个局限性对sed的高级用法进行了解。
1、高级编辑命令
命 令 | 解 释 |
---|---|
n | 覆盖读取匹配到的行的下一行至模式空间中 |
N | 追加读取匹配到的行的下一行至模式空间中 |
d | 删除多行模式空间中的所有行,并读取下一行到模式空间 |
D | 删除多行模式空间中的第一行,如果模式空间不为空,不读取下一行,而是重新执行编辑命令 |
p | 打印模式空间的所有行 |
P | 打印模式空间的第一行 |
h | 把模式空间中的内容覆盖至保持空间中 |
H | 把模式空间中的内容追加至保持空间中 |
g | 把保持空间中的内容覆盖至模式空间中 |
G | 把保持空间中的内容追加至模式空间中 |
x | 把模式空间中的内容与保持空间中的内容互换 |
2、多行模式空间
上述这些命令中,"n/N、d/D、p/P"都是处理多行模式空间的,他们大小写的功能都是类似的,只是命令影响的内容不同,都可以参照对比来记忆哦!我们通过一些例子来了解这些命令吧!
- 这里先给出一段文本(testfile):
1 is one
2 is two
3 is three
4 is four
5 is five
6 is si
x
① 显示偶数行;
[root@localhost ~]# sed -n 'n;p' testfile
2 is two
4 is four
6 is si
② 显示奇数行;
[root@localhost ~]# sed 'n;d' testfile
1 is one
3 is three
5 is five
x
③ 取出最后一行;
[root@localhost ~]# sed '$!d' testfile
x
④ 取出倒数两行;
[root@localhost ~]# sed 'N;$!D' testfile
6 is si
x
3、模式空间和保持空间内容交互
上述命令中,"h/H、g/G、x"是进行模式空间和保持空间内容交互的,它们之间同样都可以参照对比来记忆哦!我们通过一些例子来了解这些命令吧!
① 逆序显示文本内容;
[root@service ~]# cat testfile
1 is one
2 is two
3 is three
4 is four
[root@service ~]# sed '1!G;h;$!d' testfile
4 is four
3 is three
2 is two
1 is one
② 将回车替换为其他字符;
[root@service ~]# echo "a,b,c,d" | sed 's/,/\n/g'
a
b
c
d
[root@service ~]# echo "a,b,c,d" | sed 's/,/\n/g' | sed 's/\n/,/g' //没想到吧,这样替换不回去了!
a
b
c
d
#这是因为sed在读取一行时,会先把换行符去掉,处理完成后再添加上,所以上面这样进行替换是无效的
[root@service ~]# echo "a,b,c,d" |sed 's/,/\n/g' |sed 'N;s/\n/,/' //这样好像快成功了,那应该如何改进呢?
a,b
c,d
#sed提供了分支命令(b)和测试(t)来控制流程,可以跳转到指定的标签(label)位置继续执行命令
#其中标签是以冒号开头的标记,名字可以任意起一个哦,但是要前后对应哦
[root@service ~]# echo "a,b,c,d" |sed 's/,/\n/g' |sed ':label;N;s/\n/,/;b label'
a,b,c,d
③ 一些复制粘贴操作;
[root@service ~]# cat testfile
1 is one
2 is two
3 is three
4 is four
5 is five
[root@service ~]# sed '2H;4G' testfile //把第二行复制粘贴到第四行后
1 is one
2 is two
3 is three
4 is four
#为什么会出现一个空行呢?那是因为保持空间默认有一个空行。
2 is two
5 is five
6 is six
[root@service ~]# sed '2H;4G' testfile //将第二行内容覆盖到保持空间,就可以将空行去掉
1 is one
2 is two
3 is three
4 is four
2 is two
5 is five
[root@service ~]# sed '2h;2D;4G' testfile //把第二行剪切复制到第四行
1 is one
3 is three
4 is four
2 is two
5 is five
五、结束语
sed篇就总结到这里啦,如果大家发现问题请评论或私聊我,我会及时同步的!请多多支持关注!