Linux文本处理三剑客之sed(图解版哦!)

一、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篇就总结到这里啦,如果大家发现问题请评论或私聊我,我会及时同步的!请多多支持关注!

猜你喜欢

转载自blog.csdn.net/weixin_43898125/article/details/106885607
今日推荐