sed高级用法

sed高级用法

缩写功能
n读取下一行覆盖模式空间中的行
N读取下一行并追加到模式空间中的行后面,使用\n分隔
D删除模式空间的第一行,不读入下一行
d删除模式空间中的所有行,并读入下一行

在这里插入图片描述

N多行命令

多行**Next (N)**命令通过读取新的输入行,并将它添加到模式空间的现有内容之后来创建多行模式空间。模式空间最初的内容和新的输入行之间用换行符分隔。在模式空间中嵌入的换行符可以利用转义序列“\n”来匹配。在多行模式空间中,元字符“^”匹配空间中的第一个字条,而不匹配换行符后面的字符。同样,“$”只匹配模式空间中最后的换行符,而不匹配任何嵌入的换行符。在执行next命令之后,控制将被传递给脚本中的后续命令。

Next命令与next命令不同,next输出模式空间的内容,然后读取新的输入行。next命令不创建多行模式空间。

示例:

  • 需求:将第三行和第四行合并为一行
[root@hhr ~]# cat test
This is the hello line
This is the hi line 
This is the nihaosao line
This is the last line

[root@hhr ~]# sed '/nihao/{N ;s/\n/ /}' test
This is the hello line
This is the hi line 
This is the nihaosao line This is the last line

上面这个例子中,用sed匹配到nihao这行的文本在使用N将匹配到文本和下一行加入到模式空间,然后使用替换命令将换行符替换为空格,结果就是在文件中的两行合并成了一行

D 多行删除命令

删除命令**(d)**删除模式空间的内容并导致读入新的输入行,从而在脚本的顶端重新使用编辑方法。删除命令(D)稍微有些不同:它删除模式空间中直到第一个嵌入的换行符的这部分内容。它不会导致读入新的输入行,相反,它返回到脚本的顶端,将这些指令应用于模式空间剩余的内容,我们可以编写一个实现查找一系列空行并输出单个空行的脚本,以看看它们之间的区别。下面的语句使用了删除命令(d) :

当遇到一个空行时,下一行就追加到模式空间中。然后试着匹配嵌入的换行符。注意定位元字符^和$分别匹配模式空间的开始处和结束处。下面是测式文件

示例:

[root@hhr ~]# cat test
This is the hello line by 1


This is the hi line by 2


This is the nihaosao line by 3



This is the last line by 4


This is the last line by 7


//指定删除nihaosao 这行内容
[root@hhr ~]# sed '/nihaosao/{N;D}' test
This is the hello line by 1


This is the hi line by 2






This is the last line by 4


This is the last line by 7





[root@hhr ~]# cat test 
This is the hello line by 1


This is the hi line by 2



This is the nihaosao line by 3



This is the last line by 4


This is the last line by 7

//当有偶数个空行时,所有的空行都会被删除
[root@hhr ~]# sed '/^$/{N;/^\n$/d}' test
This is the hello line by 1
This is the hi line by 2

This is the nihaosao line by 3

This is the last line by 4
This is the last line by 7

总结:当有偶数个空行时,所有的空行都会被删除。仅当有奇数个空行时,有一行被保留下来。这是因为删除命令清除的是整个模式空间。一旦遇到第一个空行,就读入下一行,并且两行都被删除。如果遇到第三个空行,并且下一行不为空,那么删除命令就不会被执行,因此空行被输出。
如果使用多行Delete命令(是D不是d),就能得到我们想要的结果

示例:

[root@hhr ~]# cat test
This is the hello line by 1


This is the hi line by 2



This is the nihaosao line by 3



This is the last line by 4


This is the last line by 7

//匹配空行,进行删除,D删除时会保留一行
[root@hhr ~]# sed '/^$/{N;/^\n$/D}' test
This is the hello line by 1

This is the hi line by 2

This is the nihaosao line by 3

This is the last line by 4

This is the last line by 7

总结:多行Delete命令完成工作的原因是,当遇到两个空行时,Delete命令只删除两个空行中的第一个。下一次遍历该脚本时,这个空行将导致另一行被读入模式空间。如果那行不为空,那么两行都输出,因此确保了输出一个空行。换句话说,当模式空间中有两个空行时、只有第一个空行被删除。当一个空行后面跟有文本时,模式空间可以正常输出。

多行打印

  • P
//替换命令匹配“\nSystem”,并且用“Operating\nSystem”取代它。保留换行是很重要的,否则模式空间中就有只一行。
[root@hhr ~]# cat test
Here are examples of the UNIX
System. Where UNIX
System appears,it should be the UNIX
Operating System.

[root@hhr ~]# cat sedsrc
 /UNIX$/{
N
/\nSystem/{
s// Operating &/ 
P 
D 
}
}

[root@hhr ~]# sed -f sedsrc test
Here are examples of the UNIX Operating 
System. Where UNIX Operating 
System appears,it should be the UNIX
Operating System.

注:在sed中,&意思是用正则表达式的内容替换掉读入的内容

  • p
//接分号,表示打印特定行,如下命令只会打印出第一行与第三行
[root@hhr ~]# cat test
Here are examples of the UNIX
System. Where UNIX
System appears,it should be the UNIX
Operating System.

[root@hhr ~]# sed -n '1p;3p'  test
Here are examples of the UNIX
System appears,it should be the UNIX

//接逗号,表达连续的行,如下命令打印出第一行到第四行
[root@hhr ~]# sed -n '1,4p' test
Here are examples of the UNIX
System. Where UNIX
System appears,it should be the UNIX
Operating System.

//打印1~2行与第4[root@hhr ~]# sed -n '1,2p;4p' test
Here are examples of the UNIX
System. Where UNIX
Operating System.

模式空间与保持空间

模式空间:sed处理文本内容行的一个临时缓冲区,模式空间中的内容会主动打印到标准输出,并自动清空模式空间

保持空间:sed处理文本内容行的另一个临时缓冲区,不同的是保持空间内容不会主动清空,也不会主动打印到标准输出,而是需要sed命令来进行处理

模式空间与保持空间的关系

名称概念
模式空间(pattern space)相当于流水线,文本行在模式空间中进行处理;
保持空间(hold space)相当于仓库,在模式空间对数据进行处理时,可以把数据临时存储到保持空间;作为模式空间的一个辅助临时缓冲区,但又是相互独立,可以进行交互,命令可以寻址模式空间但是不能寻址保持空间。
命令缩写功能
Holdh或H将模式空间的内容复制或追加到保持空间
Getg 或G将保持空间的内容复制或追加到模式空间
Exchangex交换保持空间和模式空间的内容
缩写功能
h把模式空间中的内容覆盖至保持空间中
H把模式空间中的内容追加至保持空间中
g把保持空间中的内容覆盖至模式空间中
G把保持空间中的内容追加至模式空间中
x交换保持空间和模式空间的内容

G,g ,H,h使用方法

例1

  • G h
// 复制模式空间内容到保持空间,删除模式空间,将保持空间的内容追加到模式空间中输出
[root@hhr ~]# cat test
1
2
11
22
111
222

[root@hhr ~]# sed '/1/{h;d};/2/{G}' test
2
1
22
11
222
111

//把第2行放到临时仓库(hold space),然后追加到(pattern space)6行后面
[root@hhr ~]# cat test
1
2
11
22
111
222

[root@hhr ~]# sed '2h;6G' test
1
2
11
22
111
222
2

  • g H
// 复制模式空间内容到保持空间,在将匹配到模式空间的内容追加到保持空间中。然后将保持空间的内容覆盖到模式空间中输出
[root@hhr ~]# cat test
1
2
11
22
111
222

[root@hhr ~]# sed '/1/{h};/2/{H;g}' test
1
1
2
11
11
22
111
111
222

//把第一行、第三行放到临时仓库(hold space),然后覆盖掉(pattern space)第六行数据
[root@hhr ~]# cat test
1
2
11
22
111
222

[root@hhr ~]# sed '1h;3H;6g' test
1
2
11
22
111
1
11

把第一行读入临时仓库(hold space);但被后面读入的第三3行数据覆盖掉了,所以1h其实是无效的,然后第三行数据覆盖掉(pattern space)第六行数据
[root@hhr ~]#  sed '1h;3h;6g' test
1
2
11
22
111
11

例2

//小写字母转换为大写字母
[root@hhr ~]# cat test 
find the Match statement
Consult the Get statement
Using the Read statement to retrieve data

[root@hhr ~]# cat sed
/the .* statement/{
h
s/.*the (.*) statement.*/\1/		#替换命令行中提取语句的名字,并用它代替整行
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/		#转换命令将小写字母转换为大写字母
G									#保存在保持空间中的行追加到模式空间
s/(.*)\n(.*the ).*( statement.*)/\2\1\3/		#交换顺序
}

[root@hhr ~]# sed -rf sed test 
find the MATCH statement
Consult the GET statement
Using the READ statement to retrieve data

//第二行不转换大小字母
[root@hhr ~]# cat sed1
/the .* statement/{
/Get/b end
h
s/.*the (.*) statement.*/\1/
y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/
G
s/(.*)\n(.*the ).*( statement.*)/\2\1\3/
:end
}

[root@hhr ~]# sed -rf sed1 test 
find the MATCH statement
Consult the Get statement
Using the READ statement to retrieve data

  • x
    把模式空间中的内容与保持空间中的内容进行互换
[root@hhr ~]# cat hh
111111 
222222 
test33333 
4444444 
5555555

[root@hhr ~]# sed '/test/{x;p;x;}' hh
111111 
222222 

test33333 
4444444 
5555555
[root@hhr ~]# sed '/test/{x;p;}' hh
111111 
222222 


4444444 
5555555
[root@hhr ~]# sed '/test/{p;x;}' hh
111111 
222222 
test33333 

4444444 
5555555

高级的流程控制命令

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

b 分支命令基本格式为:
Branch命令用于在脚本中将控制友转移到另一行。

[address]b[label]

address:决定在哪行或哪些行执行分支命令
label:参数定义于何处分支

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

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

[root@hhr ~]# cat test1
This is the header line.
This is the first data line.
This is the second data line.
This is the last line.

[root@hhr ~]# sed '{2,3b ; s/This is/Is this/ ; s/line./test?/}' test1
Is this the header test?
This is the first data line.
This is the second data line.
Is this the last test?

因为 b 命令未指定 label 参数,因此数据流中的第2行和第3行并没有执行那两个替换命令

//文本行中出现了 first,程序的执行会直接跳到 jump1 标签之后的脚本行。如果分支命令的模式没有匹配,sed 会继续执行所有的脚本命令
[root@hhr ~]#  sed '{/first/bjump1;s/This is the/NO jump on/
> :jump1
> s/This is the/Jump here on/}' test1
NO jump on header line.
Jump here on first data line.
This is a second data line.
NO jump on last line.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值