sed的模式空间和暂存空间

关于sed(stream editor):

————sed是一个批处理(非交互式)编辑器。它可以变换来自文件或者标准输入的输入流。它常被用作管道中的过滤器。由于sed仅仅对其输入扫描一次,因此它比其他交互式编辑器(如ed)更高效。大多数linux发行版都提供了GNU sed,Mac OS X提供了BSD sed。『A Practical Guide to Linux Commands, Editors, and Shell Programming, chapter 13』

sed和awk一样,都是经典的linux神器,网上有大量相关教程,比如很不错的左耳朵耗子博客。今天想记录下之前并没有理解透的暂存空间和模式空间相关的操作(感觉自己智商一直在下降- -)。

模式空间[pattern space]是一个缓冲区,该缓冲区最初保存sed刚刚从输入中读取的行。在将数据放入暂存空间之前,他的内容为空。

暂存空间[hold space]也是一个缓冲区,该缓冲区可以在操作模式空间中的数据时用来暂存数据。

几个命令:

g: 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除
G: 将hold space中的内容append到pattern space\n后
h: 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除
H: 将pattern space中的内容append到hold space\n后
x: 交换pattern space和hold space的内容

看这样一个文件

aladdin@ubuntu:~/tmp$ cat sedtext 
line one
line two
line three

我们看这样一条命令

aladdin@ubuntu:~/tmp$ sed '2,$G;h;$!d' sedtext 
line three
line two
line one

我们来分析一下:

首先,这边sed对sedtext有3个命令的操作

2,$G:从第二行到最后一行执行G命令

h:执行h命令

$!d:删除除了最后一行的所有行

然后看其中具体操作

第一步,sed扫描到第一行,直接执行第二个命令,将模式空间中的内容拷贝到暂存空间中,此时模式空间中是line one,暂存空间中是line one,然后执行第三个命令,删除了模式空间中的第一行,此时模式空间中为空,暂存空间中为line one,

第二步,sed扫描到了第二行,会执行第一个命令G了,此时模式空间中是line two,暂存空间中是line one,G将换行符和暂存空间内容追加到模式空间中,此时模式空间是line two\nline one,暂存空间是line one,然后执行第二个命令,将模式空间中的内容拷贝到暂存空间中,此时模式空间不变,暂存空间为line two\nline one,执行第三个命令之后,模式空间为空,暂存空间为line two\nline one

第三步,sed扫描到第三行,会执行第一个命令G,模式空间为line three,暂存空间是line two\nline one,执行之后模式空间是line three\nline two\nline one,暂存空间是line two\nline one,然后h命令,模式空间不变,暂存空间line three\nline two\nline one然后不执行第三条命令,ok,结束,打印的就是最后模式空间爱你中的内容line three\nline two\nline one

我们可以看下sed '1!G;h;$!d' sedtext也可达到同样效果。

发表评论

电子邮件地址不会被公开。 必填项已用*标注