sed高级命令

78 篇文章 1 订阅
2 篇文章 0 订阅

sed执行过程

在这里插入图片描述

sed多行命令

在学习sed的时候,我们经常会被基础功能局限在单行执行操作,在 sed 命令读取缓冲区中的文本数据时,它会基于换行符的位置,将数据分成行,sed 会根据定义好的脚本命令一次处理一行数据。
但是我们也会在很多时候遇到需要对跨行数据进行命令的时候,比如说我们有时候需要在文本中查找一个很长的字符串,但是这条字符串出现在两行中,每行各包含其中的一部分,这时候使用普通的sed功能处理文本就没办法发现这种被分开的情况。
此时sed高级命令就可以有效的处理这种情况,分别是:

  • Next 命令(N):将数据流中的下一行加进来创建一个多行组来处理。
  • Delete(D):删除多行组中的一行。
  • Print(P):打印多行组中的一行。
    注:以上命令的缩写都是大写

N 多行操作命令

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

[root@localhost ~]# cat abc 
jtluo
jjlll
ccbb
aaddd[root@localhost ~]# sed '/jjl/{N;s/\n/ /}' abc 
jtluo
jjlll ccbb
aaddd

我们可以看到sed命令查找到含有jjl的那行文本,找到该行后,它会用N命令将下一行合并到查找到的那一行,然后用命令s将换行符替换成空格,结果就是本来是两行的文本通过命令变成了一行。

D多行删除命令

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

[root@localhost ~]# cat abc

On Tuesday, the Linux System
Administrator's group meeting will be held.
All System Administrators should attend.

Thank you for your attendance.

[root@localhost ~]# sed '/^$/{N ; /System/D}' lq.txt 
On Tuesday, the Linux System
Administrator's group meeting will be held.
All System Administrators should attend.

Thank you for your attendance.

sed会查找空白行,然后用 N 命令来将下一文本行添加到缓冲区。此时如果缓冲区的内容中含有单词 System,则 D 命令会删除缓冲区中的第一行。

[root@localhost ~]# cat abc 
On Tuesday, the Linux System


Administrator's group meeting will be held.



All System Administrators should attend.

Thank you for your attendance.

[root@localhost ~]# sed '/^$/{N;/^\n$/D}' abc
On Tuesday, the Linux System

Administrator's group meeting will be held.

All System Administrators should attend.

Thank you for your attendance.

当遇到两个空行时,D 命令只删除两个空行中的第一个。下一次读取该脚本时,这个空行会被另一行读入模式空间。如果那行不为空,那么两行都输出,因此确保了输出一个空行。说白点就是,当模式空间中有两个空行时,只有第一个空行被删除,当一个空行后面跟有文本时,不对模式空间里的内容处理。

h,H,g,G使用

由于各种各样的原因,比如用户希望在某个条件下脚本中的某个命令被执行,或者希望模式空间得到保留以便下一次的处理,都有可能使得sed在处理文件的时候不按照正常的流程来进行。这个时候,sed设置了一些高级命令来满足用户的要求。
在这里插入图片描述
h: 将模式空间的内容复制到保持空间

H: 将模式空间的内容追加到保持空间

g: 将保持空间的内容复制到模式空间

G: 将保持空间的内容追加到模式空间

x: 把保持空间的内容和模式空间的内容进行交换

原文件

[root@localhost ~]# cat abc 
hello the world
hello minger
golang
python
c/c++
linux
[root@localhost ~]# sed '2d;5g' abc 
hello the world
golang
python

linux

上面的信息,sed命令在读取文件的第2行时将整行数据复制到保留空间,并将保留空间中原有的回车符覆盖了。

使用2h,5G

[root@localhost ~]# sed '2h;5G' abc 
hello the world
hello minger
golang
python
c/c++
hello minger
linux

sed的正常流程是先读取数据行放入模式空间,然后匹配条件执行sed指令,如果有多个指令,则只有最后一个指令被执行后才会输出模式空间的内容,接着读取文件的一下行内容,依次类推,知道文件读取结束时退出sed程序,但是如果使用n指令,则会改变这样的正常流程,sed遇到n指令立刻输出当前的模式中的内容,直接读取输入文件的下一行数据到模式空间。

小写字母替换为大写字母

[root@localhost ~]# sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' abc 
HELLO THE WORLD
HELLO MINGER
GOLANG
PYTHON
C/C++
LINUX

b 分支命令

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

命令格式:[address]b [label]

[root@localhost ~]# cat data2.txt
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/Is this/ ; s/line./test?/}' data2.txt
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行并没有执行那两个替换命令。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值