目 录CONTENT

文章目录

Sed高级命令

ZiChen D
2021-09-17 / 0 评论 / 0 点赞 / 236 阅读 / 3,376 字 / 正在检测是否收录...

Sed高级命令

Sed命令的高级脚本都做一件共同的事,那就是它们改变了执行或控制的流程顺序。通常,一行被读入模式空间并且用脚本中的每个命令(一个接一个地)应用于那一行。当达到脚本的底部时,输出这一行并且清空模式空间。然后新行被读入模式空间。并且控制被转移回脚本的顶端。这是 sed 脚本中正常的控制流。


脚本由于各种原因中断或暂停了正常的控制流。它们也许想阻止脚本中的命令被执行,某些特定的情况除外, 或者阻止模式空间的内容被清除。 更改控制流会使脚本更加难以阅读和理解。事实上,写脚本比读脚本更容易。 当你编写很难的脚本时,测式它来看看命令如何工作对你会有好处。

亲自验证结果比只是简单地阅读能更好的理解脚本。

多行模式空间

在前面正则表达式的学习中。 像 grep 这样的程序尝试在单个输入行上匹配一个模式。这就使它很难匹配一个在一行的结尾,处开始。并在下一行的开始处结束的短语。其他一些模式只有当在多行上重复时才有意义。

多行模式空间:N、n

N(Next):追加下一行

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

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

n:读取下一行

读取下一行到pattern space(模式空间)。由于pattern space中有按照正常流程读取的内容,使用n命令后,pattern space中又有了一行,此时,pattern space中有2行内容,但是先读取的那一行不会被取代、覆盖或删除;当n命令后,还有其他命令p的时候,此时打印出的结果是n命令读取的那一行的内容。

图解:
image.png

image.png

步骤:

  1. 在进行输入时会遇到一串字符遇到末尾只能转行写,这就导致我们在查找时并不好查找到,所以就用Sed高级命令中的N来进行查找
  2. 利用N可以将多行文本转为一行文本来方便查看和操作
    实例:
[root@localhost ~]# cat test.txt
first line
Second line
Third line

[root@localhost ~]# sed '/first/{N;s/\n/ /}' test.txt 
first line,Second line
Third line

多行删除:D、d

D(Delete):多行删除

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

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

当有偶数个空行时,所有的空行都会被删除。仅当有奇数个空行时,有一行被保留下来。这是因为删除命令清除的是整个模式空间。一旦遇到第一个空行,就读入下一行。并且两行都被删除。如果遇到第三个空行。并且下一行不为空,那么删除命令就不会被执行,因此空行被输出。

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

d:删除
前面已经展示了删除命令(d)的示例。它采用一个地址,如果行匹配这个地址就删除模式空间的内容。
删除命令还是一个可以改变脚本中的控制流的命令。这是因为一旦执行这个命令,那么在"空的"模式空间(注4)中就不会再有命令执行。删除命令会导致读取新输入行,而编辑脚本则从头开始新的一轮(这一行为和 next命令的行为相同,本章后面将介绍 next命令)。
重要的是;如果某行匹配这个地址,那么就删除整个行,而不只是删除行中匹配的部分(要删除行的一部分,可以使用替换命令并指定一个空的替换)。

实例:

[root@localhost ~]# cat test.txt 

first line

Second line
Third line
[root@localhost ~]# sed '/^$/{N ; /first/D}' test.txt 
first line

Second line
Third line

多行打印:P

P(Print):多行打印
多行打印(Print)命令与小写字母的 print命令稍有不同。该命令输出多行模式空间的第一部分,直到第一个嵌入的换行符为止。在执行完脚本的最后一个命令之后,模式空间的内容自动输出(-n 选项或#n抑制这个默认的动作)。因此,当默认的输出被抑制或者脚本中的控制流更改. 以至不能到达脚本的底部时,需要使用打印命令(P或p).Print命令经常出现在 Next命令之后和Delete命令之前。这3个命令能建立一个输入/输出循环,用来维护两行的模式空间,但是一次只输出一行。这个循环的目的是只输出模式空间的第一行,然后返回到脚本的顶端将所有的命令应用于模式空间的第二行。没有这个循环,当执行脚本中的最后一个命令时,模式空间中的这两行都将被输出。创建多行模式空间以匹配第一行结尾处的"UNIX"和第二行开始处的"System"。如果发现"UNIX System"跨越两行,那么我们将它变成"UNIX Operating System"。建立这个循环以返回到脚本的顶端,并寻找第二行结尾处的

保持空间

H:模式空间追加到保持空间
G:保持空间追加到模式空间
h:模式空间覆盖保持空间
g:保持空间覆盖模式空间
命令中的每一条都可以利用一个地址来指定一行或行范围.空穴(h,H)命令将数据移至保持空间、而得到(G.G)命令将保持空间的数据移回到模式空间。同一命令的小写字母和大写字母之间的差别是,小字字母命令改写目的缓存区的内容,而大写字母命令追加缓存区的现有内容.

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

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

b分支命令

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

b 分支命令基本格式为:
[address]b [label]

0

评论区