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) 编辑 收藏 举报