sed之G、H、g、h使用

什么是sed?

sed是面向流的行编辑器,所谓面向流,是指接受标准输入的输入,输出内容到标准输出上。

sed如何处理数据?

sed在正常情况下,将处理的行读入模式空间(pattern space),脚本中的“sed-command(sed命令)”就一条接着一条进行处理,知道脚本执行完毕。然后该行呗输出,模式(pattern space)被清空;接着,在重复执行刚才的动作,文件中的新的一行被读入,直到文件处理完毕。

sed

什么是Pattern Space,什么是Hold Space?

pattern space相当于车间sed把流内容在这里处理。

hold space相当于仓库,加工的半成品在这里临时储存。

PS:你可以将pattern space看成是一个流水线,所有的动作都是在“流水线”上执行的;而hold space是一个“仓库”,“流水线”上的东东都可以放到这里。

为什么要使用sed高级命令(G、H、g、h、n、N、x)?

由于各种各样的原因,比如用户希望在某个条件下脚本中的某个命令被执行,或者希望模式空间得到保留以便下一次的处理,都有可能使得sed在处理文件的时候不按照正常的流程来进行。这个时候,sed设置了一些高级命令来满足用户的要求。

sed命令:

  • g:[address[,address]]g 将hold space中的内容拷贝到pattern space中,原来pattern space里的内容清除

  • G:[address[,address]]G 将hold space中的内容append到pattern space\n后

  • h:[address[,address]]h 将pattern space中的内容拷贝到hold space中,原来的hold space里的内容被清除

  • H:[address[,address]]H 将pattern space中的内容append到hold space\n后

  • d:[address[,address]]d 删除pattern中的所有行,并读入下一新行到pattern中

  • D:[address[,address]]D 删除multiline pattern中的第一行,不读入下一行

PS:不论是使用G、g还是H、h,它们都是将hold space里面的内容“copy”到pattern space中或者将pattern space中的内容“copy”到hold space中。

附上英文的解释(注意其中的高亮单词):

The “h” command copies the pattern buffer into the hold buffer. The pattern buffer is unchanged.

Instead of exchanging the hold space with the pattern space, you can copy the hold space to the pattern space with the “g” command. This deletes the pattern space. If you want to append to the pattern space, use the “G” command. This adds a new line to the pattern space, and copies the hold space after the new line.

示例:用sed模拟出tac的功能(倒序输出)。

文件内容

cat mm

1

2

3

解决方法:
sed ‘1!G;h;$!d’mm

ps:1!G第1行不 执行“G”命令,从第2行开始执行。

   $!d,最后一行不删除(保留最后1行)

图解分析过程

P:Pattern Space

H:Hold Space

蓝色:Hold Space中的数据

绿色:Pattern Space中的数据

sed2

sed在特定的行前面或者后面加入另一个文件内容

如下图将t2.txt 的内容插入到t1.txt中3的前面

sed -i '/3/{h;s/.*/cat t2.txt/e;G}' t1.txt

t1

解析:匹配到3这一行时,h -> 放到仓库,然后把3替换成了t2.txt里的内容,也就是2,然后G -> 把仓库里的3追加上去这样2就到3的前面了

如下图将t2.txt 的内容插入到t1.txt中3的后面
t2

sed -i '/3/{p;s/.*/cat t2.txt/e}' t1.txt

解析: 匹配到3时在打印一个3,相当于1 3 3, 然后面的3替换成t2.txt中的内容

Q.E.D.