Linux sed --模拟空间&保留空间

时间:2021-10-16 15:30:12

Pattern space和Hold space

Sed是对数据流进行操作的一个强大的工具,大家已经经常使用到sed对文本进行修改,替换。这里就不介绍sed的使用方法了,本文主要介绍sed中的Pattern space和Hold space。理解了这两个概念有助于从本质上理解sed处理数据流的方式,尤其是像实现逆转、只输出奇数或偶数行等等功能,Pattern space和Hold space即模式空间和保留空间(也可以称之为缓冲区),保留空间的初始为空,我们可以认为是一个空行。下面图示了sed中的输入流,输出流,模式空间以及保留空间:

先简单介绍下sed的一般工作模式(在没有利用到Hold space的时候),pattern space每次从input中取一行数据到pattern space中,然后经过一些处理,将一行数据放入output中,然后output会输出到屏幕(默认为屏幕,也可以是文件)。记住,此时pattern space还储存着这一行数据,直到input再放入第二行数据取代第一行数据。

当sed的命令为sed [-n] ‘[hHgGx]p’file格式时,需要涉及到hold space,其实我们可以简单的讲hold space理解为sed的一个缓冲区就好了,只是这个缓冲区不会直接进行输出,并且只有pattern space可以对其进行操作,放入或者拿出数据(如上图所示)。

 下面解释下[hHgGx]这几个参数:(以file做例子,file中的数据为:

Man sed中的解释为:

h/H:copy/append pattern space to hold space(复制或者追加模式空间的数据至保留空间);

g/G:copy/append hold space to pattern space(复制或者追加保留空间的数据至模式空间);

x:exchange the contents of pattern space and hold space(交换模式空间和保留空间的数据);

一般会将h/H和g/G以及x联合起来用,可以达到栈和队列的使用目的。

G:sed 'G' file

因为hold space的初始为一个空行,并且始终没有修改其中的数据,一直保持的是空行,所以在每次执行G命令时,会将空行追加到每行数据之后。

x:sed 'x;G' file

因为开始x命令将hold space的空行和pattern space中的111111111交换,然后G命令又将111111111追加到pattern apace的空行之后,然后输出了

,此时hold space中依旧为111111111,接着pattern space中进入22222222,x命令将hold space的111111111和pattern space中的22222222交换,然后G命令又将22222222追加到pattern apace的111111111之后,然后输出了

,依次类推,就输出了结果。可是看到过程如表格所示:

命令

sed 'x;G' file

 

 

 

 

 

hold space

 

pattern space

 

 

执行命令过程

执行前

执行后

执行前

执行后

输出

执行x命令

空行

111111111

111111111

空行

无输出

执行G命令

111111111

111111111

空行

空行

111111111

执行x命令

111111111

22222222

22222222

111111111

无输出

执行G命令

22222222

22222222

111111111

111111111

22222222

执行x命令

22222222

3333333

3333333

22222222

无输出

执行G命令

3333333

3333333

22222222

22222222

3333333

执行x命令

………………………………

 

 

 

 

大家应该能思考到为什么最后只有一个9

 

 

 

 

 

h:sed 'h;G' file

命令进行操作的思路,大家可以参照x命令的方法进行一步步的演示。

H:sed 'H;x' file

g:sed '1h;g;x' file

下面解释下'1h;g;x'中“1“的含义,表示只有第一行执行h命令,将111111111复制到hold space中去,之后每次执行g命令的时候,都是从hold space中将111111111复制出来,覆盖掉了pattern space中的数据,所以结果显示为打印了9行111111111。

而$表示只有最后一行执行这个命令。

在1或$和命令中添加“!“,表示只有第一行或者最后一行不执行这个命令。

有关于更改多的命令n/N、d/D等,请大家自己查阅man sed或者其他资料。在遇到复杂的命令的时候,希望大家可以手动进行画图来执行每个命令,这样就比较清楚了。

下面有4个例子来解释下选项n的作用:

  1. sed '' file,这句命令会将output中的数据进行输出:
  1. sed -n 'p' file,这句命令虽然显示的结果和上一个一样,但机制是不同的,这句命令是要求输出pattern space中的数据;如果大家觉得这个说法有点模糊,再继续看下面的例子。
  2. sed 'p' file,先看结果:

这条命令输出了两遍,为什么呢?因为不仅将每次output中的数据进行了输出,接着又将pattern space中的数据再要求输出一次。

  1. sed -n '' file,大家应该能猜到这个输出什么结果了,那就是空,因为选项-n指明了要讲pattern space中的数据进行输出,而缺少了p命令,所以不能将pattern space中的数据进行输出。