sed高级用法

sed高级用法

sed有模式空间和保持空间,保持空间在默认情况下是不会被使用到的,只有在某些命令下才会被使用。

(1)模式空间:进行文本处理。

(2)保持空间:把数据临时存放在这里。

  • g:将保持空间的内容拷贝到模式空间中,原模式空间将被清零。

  • G:将保持空间的内容追加到模式空间\n之后。

  • h:将模式空间的内容拷贝到保持空间中,原保持空间将被清零。

  • H:将模式空间的内容追加到保持空间\n之后。

  • d:删除模式空间中的所有行,并读入下一行。

  • D:删除模式空间的第一行,不读入下一行。

  • x:交换内容

  • n:读取下一行到模式空间。

  • N:将下一行追加到模式空间后

1.N

N 命令会将下一行文本内容添加到缓冲区已有数据之后(之间用换行符分隔),从而使前后两个文本行同时位于缓冲区中,sed 命令会将这两行数据当成一行来处理。

[root@localhost ~]# cat test 
wo shi cai ao cheng ta die 
xx 
zz 
sb
chenshunli
[root@localhost ~]# sed '/sb/N;s/\n//' test
wo shi cai ao cheng ta die 
xx 
zz 
sbchenshunli
//在这个例子中,sed 命令查找含有单词 sb 的那行文本。找到该行后,它会用 N 命令将下一行合并到那行,然后用替换命令 s 将换行符替换成空。结果是,文本文件中的两行在 sed 的输出中成了一行。

[root@localhost ~]# cat test 
On Tuesday, the Linux System
Administrator's group meeting will be held.
[root@localhost ~]# sed 'N;s/System\nAdministrator/Desktop User/' test
On Tuesday, the Linux Desktop User's group meeting will be held
//查找单行中短语的替换命令在数据流的后一行也能正常工作,多行替换命令则会负责短语出现在数据流中间的情


2.D

D 多行删除命令

sed 不仅提供了单行删除命令(d),也提供了多行删除命令 D,其作用是只删除缓冲区中的第一行,也就是说,D 命令将缓冲区中第一个换行符(包括换行符)之前的内容删除掉。

[root@localhost ~]# cat test 
On Tuesday, the Linux System
Administrator's group meeting will be held
All System Administrators should attend.

[root@localhost ~]# sed 'N;/System\nAdministrator/D' test
Administrator's group meeting will be held
All System Administrators should attend.
//文本的第二行被 N 命令加到了缓冲区,因此 sed 命令第一次匹配就是成功,而 D 命令会将缓冲区中第一个换行符之前(也就是第一行)的数据删除,所以,得到了如上所示的结果

[root@localhost ~]# cat data 

sbxk 

sbcac
erzicac


sbcsl
[root@localhost ~]# sed '/^$/{N; /sbxk/D}' data
sbxk 

sbcac
erzicac


sbcsl
//sed会查找空白行,然后用 N 命令来将下一文本行添加到缓冲区。此时如果缓冲区的内容中含有单词 sbxk,则 D 命令会删除缓冲区中的第一行。
[root@localhost ~]# sed '                   
/^$/{ 
N;/sb/D
N;/csl/D
}' data
sbxk 
sbcac
erzicac

sbcsl

3.h和g,G

通常,在使用 h 或 H 命令将字符串移动到保持空间后,最终还要用 g、G 或 x 命令将保存的字符串移回模式空间。保持空间最直接的作用是,一旦我们将模式空间中所有的文件复制到保持空间中,就可以清空模式空间来加载其他要处理的文本内容

Hold命令用模式空间的内容取代保持空间的内容。

[root@localhost ~]# cat data 
hello the world 
hello minger 
golang
python 
linux 
[root@localhost ~]# sed '2h;5G' data
hello the world 
hello minger 
golang
python 
linux 
hello minger 
[root@localhost ~]# sed '2h;5g' data
hello the world 
hello minger 
golang
python 
hello minger 
[root@localhost ~]# cat data 
A
a
B
b
C
c
D
d
[root@localhost ~]# sed -n 'h;n;p;g;p' data
a
A
b
B
c
C
d
D

在这里插入图片描述

4.H和g,G

将模式空间的内容追加到保持空间Hole命令在保持空间的内容之后放置一个换行符,且后面跟随模式空间的内容(即使保持空间是空的,换行符也被追加到保持空间中)。

[root@localhost ~]# cat data 
hello the world 
hello minger 
golang
python 
linux 
[root@localhost ~]# sed '2H;5g' data
hello the world 
hello minger 
golang
python 

hello minger 
[root@localhost ~]# sed '2H;5G' data
hello the world 
hello minger 
golang
python 
linux 

hello minger 
[root@localhost ~]# cat test 
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@localhost ~]# sed -n '/first/{h;p;n;p;g;p}' test
This is the first data line.
This is the second data line.
This is the first data line.

这个例子的运行过程是这样的:

sed脚本命令用正则表达式过滤出含有单词first的行;
当含有单词 first 的行出现时,h 命令将该行放到保持空间;
p 命令打印模式空间也就是第一个数据行的内容;
n 命令提取数据流中的下一行(This is the second data line),并将它放到模式空间;
p 命令打印模式空间的内容,现在是第二个数据行;
g 命令将保持空间的内容(This is the first data line)放回模式空间,替换当前文本;
p 命令打印模式空间的当前内容,现在变回第一个数据行了。

5.x

交换内容

[root@localhost ~]# cat test2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@localhost ~]# sed '/header/h;/first/x' test2
This is the header line.
This is the header line.
This is the second data line.
This is the last line.

h 将匹配到的name 行 ,添加至保持空间
x 将保持空间的内容和模式空间互换

6.b

b 分支命令

通常,sed 程序的执行过程会从第一个脚本命令开始,一直执行到最后一个脚本命令(D 命令是个例外,它会强制 sed 返回到脚本的顶部,而不读取新的行)。sed 提供了 b 分支命令来改变命令脚本的执行流程,其结果与结构化编程类似。

b 分支命令基本格式为:

[address]b [label]

其中,address 参数决定了哪些行的数据会触发分支命令,label 参数定义了要跳转到的位置。

需要注意的是,如果没有加 label 参数,跳转命令会跳转到脚本的结尾,比如

[root@localhost ~]# cat test2
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.
[root@localhost ~]# sed '2,3b;s/This is/Ls this/;s/line./test?/' test2
Ls this the header test?
This is the first data line.
This is the second data line.
Ls this the last test?
//可以看到,因为 b 命令未指定 label 参数,因此数据流中的第2行和第3行并没有执行那两个替换命令。

//如果我们不想直接跳到脚本的结尾,可以为 b 命令指定一个标签(也就是格式中的 label,最多为 7 个字符长度)。在使用此该标签时,要以冒号开始(比如 :label2),并将其放到要跳过的脚本命令之后。这样,当 sed 命令匹配并处理该行文本时,会跳过标签之前所有的脚本命令,但会执行标签之后的脚本命令。
[root@localhost ~]# sed '{/first/b jump1;s/This is the/No jump on/                                           
:jump1 
s/This is the/Jumpe here on/}' test2 

No jump on header line.
Jumpe here on first data line.
No jump on second data line.
No jump on last line.

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值