sed的工作原理(pattern space 和 hold space)

sed是一个非交互式的流编辑器(stream editor)。所谓非交互式,是指使用sed只能在命令行下输入编辑命令来编辑文本,然后在屏幕上查看输出;而所谓流编辑器,是指sed每次只从文件(或输入)读入一行,然后对该行进行指定的处理,并将结果输出到屏幕(除非取消了屏幕输出又没有显式地使用打印命令),接着读入下一行。整个文件像流水一样被逐行处理然后逐行输出。

sed一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为“模式空间”(pattern space),接着用sed命令处理缓冲区(pattern space)中的内容,处理完成后,把缓冲区(pattern space)的内容送往屏幕。接着清空缓冲区(pattern space),处理下一行,这样不断重复,直到文件末尾。

pattern space(模式空间)相当于车间sed把流内容在这里处理;
hold space(保留空间)相当于仓库,加工的半成品在这里临时储存(当然加工完的成品也在这里存储)。

How sed Works:


先读入一行,去掉尾部换行符,存入pattern space,执行编辑命令。
处理完毕,除非加了-n参数,把现在的pattern space打印出来,在后边打印曾去掉的换行符。
把pattern space内容给hold space,把pattern space置空。
接着读下一行,处理下一行。

 

一种非平凡情况,一个文件仅一行,尾部没换行,sed只打印,不会尾部加换行,但若在尾部又附加了输出,他会再补上那个换行。

经典实例解释:


下面的解释小而简洁,但是可以将它作为一个准则,帮助你理解sed命令。

 

SED在哪里缓存数据

SED维护两个数据缓冲区:主动模式空间(pattern space)和辅助保留空间(hold space)。在“通常”操作中,SED从输入流读取一行存入pattern space,这里就是文本编辑操作发生的地方。hold space最初是空的,但也有在pattern space和hold space直接移动数据的命令。

这里,我们用SED的“x”命令来做一个小实验:

'x'  - 交换pattern space和hold space的内容

一个文件包含三行:

#cat file
line1
line2
line3
#

用SED x 命令操作后:
#sed 'x' file



line1
line2
#

解释:

 

#sed 'x' file 
        <-- 第一行是空的,因为hold space和pattern space交换了内容,记住最初的时候hold space是空的;在处理完第一行后,现在hold space的内容是line1。
line1    <-- 第二行输出是line1,现在hold space的内容是line2,and so on a so forth . ^_^
line2
#

------------------

操作pattern space和hold space的命令:


$ man sed
       d      Delete pattern space.  Start next cycle.
              删除pattern space的内容,开始下一个循环.

       h H    Copy/append pattern space to hold space.
              复制/追加pattern space的内容到hold space.
       g G    Copy/append hold space to pattern space.
              复制/追加hold space的内容到pattern space.
       x      Exchange the contents of the hold and pattern spaces.
              交换hold space和pattern space的内容.

课后理解:


1)交换第1行和第2行的内容


$ sed -n '1{h;n;x;H;x};p' filename

2)用sed实现tac的功能


$ sed -n -e '1!G;h;$p' filename

$ sed -e '1!G;h;$!d' filename

这2种写法都相当于tac filename。
--------------------------------------------------下面例子摘自耗子叔的酷壳,(*^__^*) 嘻嘻……------------------------------------------------------------
第一个示例:
$ sed 'H;g' t.txt
one
 
one
two
 
one
two
three

是不是有点没看懂,我作个图你就看懂了。

 

第二个示例,反序了一个文件的行:

$ sed '1!G;h;$!d' t.txt
three
two
one

其中的 ’1!G;h;$!d’ 可拆解为三个命令

  • 1!G —— 只有第一行不执行G命令,将hold space中的内容append回到pattern space
  • h —— 第一行都执行h命令,将pattern space中的内容拷贝到hold space中
  • $!d —— 除了最后一行不执行d命令,其它行都执行d命令,删除当前行

这个执行序列很难理解,做个图如下大家就明白了:

就先说这么多吧,希望对大家有用。

(全文完)

posted on 2014-03-17 21:42  theCambrian.cpp  阅读(3750)  评论(1编辑  收藏  举报

导航