sed之高级命令的解析

            sed工作机制中另一个逻辑空间用于作为模式空间的好帮手,就是叫保持空间(hold space),在模式空间中处理一行内容会继续处理下一行,那么对于处理过的行可能还有其他处理,因此可以先把处理好的数据存放在hold space 中,然后等到全部处理好之后在回到模式空间中。简单的可以说是用于和模式空间配合使用交换空间里的数据达到想要的结果

其中一般用到hold space的称作高级编辑命令:

高级编辑命令:

h:把模式空间中的内容覆盖至保持空间中
H:把模式空间中的内容追加至保持空间中
g:把保持空间中的内容覆盖至模式空间中
G:把保持空间中的内容追加至模式空间中
n:覆盖读取匹配到的行的下一行至模式空间中
N:追加读取匹配到的行的下一行至模式空间中
d:删除模式空间中的行
D:删除多行模式空间中的首行
x:把模式空间中的内容与保持空间中的内容替换

 高级命令示例解析: 

 1.sed -n ‘n;p‘ file  显示文件中偶数行(即2、4、6、8……行)

-n:不打印默认打印到屏幕上的所有行(静默模式)

n:覆盖读取匹配到的行的下一行至模式空间中

p:打印符合pattern psace的行

    [root@localhost ~]# cat SED.txt | tr -d '\n'
    12345678910    //这里我把换行删除为节约空间便于观察
    [root@localhost ~]# sed -n 'n;p' SED.txt 
      2
      4
      6
      8
      10

        解析:

            当sed读取文件中的第一行,来到执行“n”命令,而“n”命令的作用是读取匹配到的下一行到模式空间,也就是说我们现在模式空间中的是第一行,而“n”命令需要我们去读它的下一行,也就是把第二行读到模式空间,把第一行覆盖了,而后又执行“p”命令,则是打印出pattern space 中的行,即打印第2行,由于我们使用“ -n ” 选项默认不打印pattern space 读过的内容,而“p”命令是打印pattern space 符合条件的,所以打印第二行;

   接着读取第三行,因为第二行在读取第一行的时候已经被命令调用去读取第二行。so读取第三行,然后执行“n”命令,又去读取第4行,从而覆盖掉了第三行,然后打印第4行;………sed命令就这么一直执行下去,符合条件输出的都是双数行 。输出的也就是偶数行

2.sed ’1!G;h;$!d' file 逆序显示文件

        G:把保持空间中的内容追加至模式空间中        
        h:把模式空间中的内容覆盖至保持空间中
        d:删除行
        $:  最后一行
        !:取反
        (1!G):除了第一行,其他都要执行G命令
        ($!d):除了最后一行,其他都有要执行“d”(删除)命令
    [root@localhost ~]# sed  '1!G;h;$!d' SED.txt 
        10
        9
        8
        7
        6
        5
        4
        3
        2
        1

    解析:

        读取文件第一行,判断是不是第一行,如果是就不执行G命令,如果不是,就执行G命令,现在读取的是第一行,所以不执行G命令,然后来到执行第二个命令(h),现在模式空间中的是第一行,则把第一行复制覆盖到保持空间中,然后在执行下一个命令,判断模式空间中的是不是最后一行,如果是,就不删除,否则删除,现在模式空间中的是第一行,所以删除,保持空间中的内容不变;

接着读取第二行,判断出不是第一行,则执行“G”命令,把保持空间中原有的第一行追加读取到模式空间中(现在模式空间中的顺序为2在前1在后,因为是追加上去的),然后执行“h”命令,把模式空间中的行复制覆盖到保持空间中,因此现在保持空间中的顺序为第二行在前,第一行在后,然后判断是否为最后一行时,模式空间中的第二行和第一行则被删除掉; 

再接着读取第三行,在依次进行判断,得到最后的结果就是倒序显示文件中的行。(绕了那么多,其实就是tac命令解决,这只是为了理解其含义)

  

  3.sed '$!d' file 取出文件最后一行

        $:最后一行        
        d:删除行
        [root@localhost ~]# sed '$!d' SED.txt 
        10

     解析:

        读取第一行到模式空间中,第一个命令判断是否为最后一行,如果是,则不删除,否则删除,由此可知,只有最后一行不删除,其他全删除,就留下最后一行。则取出文件最后一行。

    4.sed ‘$!N;$!D' file  取出文件 最后两行2

    N:追加读取匹配到的行的下一行至模式空间中    
    D:删除多行模式空间中的首行
    $:最后一行
  [root@localhost ~]# sed '$!N;$!D' SED.txt 
    9
    10

     解析:

        读取第一行,然后执行第一个命令,(如果不是最后一行则追加读取匹配到的当前行的下一行到模式空间中,)此时是第一行,然后执行"N"命令,把当前行的下一行追加读取到当前的模式空间中,此时模式空间中为12两行,然后再执行后面的命令(如果不是最后一行,则删除当前多行中的首行,即删除第一行,)此时模式空间中还剩下第二行(暂时保存在保持空间中,虽然没有命令说要将行放到保持空间中,保持空间如果没有命令指定用,则会用来保存模式空间处理过的行,以便模式空间之后需要使用);

则又去读取第三行,然后判断不是最后一行, 则追加当前的第三行的下一行(第四行)到模式空间中,(此时模式空间中加上原有剩下的第二行,为2和4行,)然后再判断不是最后一行,则删除当前模式空间中的第一行,留下第四行。

则继续读取第五行,此时为最后一行,然后第一个命令不执行“N”命令,再接着不执行D命令,即现在模式空间中的所剩下的行为第4行和第5行,然后打印模式空间的行出来即为文件的最后两行。

    5.sed ‘/^$/d;G file  删除原文件中的空白行,再添加空行到每一行的下面

这比较简单,大伙试着自己分析吧,只要把高级命令各个所代表含义记熟这都不是事。(我也留几个以后看的忘了好继续分析理解)

    6.sed ’n;d' file 显示奇数行

这和第一题恰好相反

    7.sed 'G' file  在原文件中的每一行添加空行,包括原有的空白行后面也添加空白行

这更不用解释了

加油,付出就一定会有收获的!!!

原创文章,作者:Lii,如若转载,请注明出处:http://www.178linux.com/31816