zoukankan      html  css  js  c++  java
  • (转)通过几个例子看sed的模式空间与保持空间

    原文:https://www.cnblogs.com/276815076/p/7879666.html

    SED之所以能以行为单位的编辑或修改文本,其原因在于它使用了两个空间:一个是活动的“模式空间(pattern space)”,另一个是起辅助作用的“暂存缓冲区(holdingspace)这2个空间的使用。

    sed编辑器逐行处理文件,并将输出结果打印到屏幕上。sed命令将当前处理的行读入模式空间(pattern space)进行处理,sed在该行上执行完所有命令后就将处理好的行打印到屏幕上(除非之前的命令删除了该行),sed处理完一行就将其从模式空间中删除,然后将下一行读入模式空间,进行处理、显示。处理完文件的最后一行,sed便结束运行。sed在临时缓冲区(模式空间)对文件进行处理,所以不会修改原文件,除非显示指明-i选项。

    sed之所以能以行为单位的编辑或修改文本,其原因在于它使用了两个空间:一个是活动的“模式空间(pattern space)”,另一个是起辅助作用的“保持空间(hold space)这2个空间的使用。

    模式空间:可以想成工程里面的流水线,数据之间在它上面进行处理,用于处理文本行。

    保持空间:可以想象成仓库,我们在进行数据处理的时候,作为数据的暂存区域,用于保留文本行,是保存已经处理过的输入行,默认有一个空行。 

    与模式空间和暂存空间(hold space)相关的命令:

    n 输出模式空间行,读取下一行替换当前模式空间的行,执行下一条处理命令而非第一条命令。

    N 读入下一行,追加到模式空间行后面,此时模式空间有两行。

    h 把模式空间的内容复制到保留空间,覆盖模式

    H 把模式空间的内容追加到保留空间,追加模式

    g 把保留空间的内容复制到模式空间,覆盖模式

    G 把保留空间的内容追加到模式空间,追加模式

    x 将暂存空间的内容于模式空间里的当前行互换。

    ! 对所选行以外的所有行应用命令。

    注意:暂存空间里默认存储一个空行。

    例子一 
    sed G 
    在文件每一行下面输出一个空行 

    代码:

    $ cat foo 
    11111111111111 
    22222222222222 
    33333333333333 
    44444444444444 
    55555555555555 

    $ sed G foo 
    11111111111111 

    22222222222222 

    33333333333333 

    44444444444444 

    55555555555555 


    解释: 

    sed 中 G 的用法 
    The G function appends the contents of the holding area to the contents of the pattern space. The former and new contents are separated by a newline. The maximum number of addresses is two. 

    hold space : 保持空间(或者叫保留空间、缓冲区),初始为空 
    pattern space :模式空间 

    在上面的例子中,将为空的hold space附加到文件的每一行后面,所以结果是每一行后面多了一个空行 

    引申出: 
    sed '/^$/d;G' 
    在文件的每一个非空行下面输出一个空行 
    sed '/^$/d;G;G' 
    在文件的每一个非空行下面输出两个空行 

    代码:

    $ cat foo 
    11111111111111 
    22222222222222 

    33333333333333 
    44444444444444 
    55555555555555 

    $ sed '/^$/d;G' foo 
    11111111111111 

    22222222222222 

    33333333333333 

    44444444444444 

    55555555555555 



    注:有时会有一些由空格符或者TAB组成的空行,前面的正则式 ^$ 就不能匹配到这样的行,则可以这样 
    sed '/[[:space:]]/d;G' 


    例子二 
    sed '/regex/{x;p;x;}' 
    在匹配regex的所有行前面插入一个空行 

    代码:

    $ cat foo 
    11111111111111 
    22222222222222 
    test33333333333333 
    44444444444444 
    55555555555555 

    $ sed '/test/{x;p;x;}' foo 
    11111111111111 
    22222222222222 

    test33333333333333 
    44444444444444 
    55555555555555 



    解释: 
    sed 中 x 的用法 
    The exchange function interchanges the contents of the pattern space and the holding area. The maximum number of addresses is two. 
    即交换保持空间hold space和模式空间pattern space的内容 

    sed 中 p 的作用是把模式空间复制到标准输出。 

    分析一下该命令执行过程中保持空间和模式空间的内容 

    命令 保持空间 模式空间 
    x 执行前:null 执行后:test 执行前:test 执行后:null 
    p 执行前:null 执行后:test 执行前:test 执行后:null 输出一个空行 
    x 执行前:test 执行后:null 执行前:null 执行后:test  

    (注:把test所在的行简写为test了) 

    引申: 
    可以试验一下 sed '/test/{x;p;}' foo 或者 sed '/test/{p;x;}' foo 等,看看结果,体会两个空间的变化 

    相应的: 
    sed '/regex/G' 是在匹配regex的所有行下面输出一个空行 
    sed '/regex/{x;p;x;G;}' 是在匹配regex的所有行前面和下面都输出一个空行 


    例子三 
    sed 'n;G;' 
    在文件的偶数行下面插入一个空行 

    代码:

    $ cat foo 
    11111111111111 
    22222222222222 
    33333333333333 
    44444444444444 
    55555555555555 

    $ sed 'n;G;' foo 
    11111111111111 
    22222222222222 

    33333333333333 
    44444444444444 

    55555555555555 


    解释: 
    sed 中 n 的用法:将模式空间拷贝于标准输出。用输入的下一行替换模式空间。 

    执行 n 以后将第一行输出到标准输出以后,然后第二行进入模式空间,根据前面对 G 的解释,会在第二行后面插入一个空行,然后输出;再执行 n 将第三行输出到标准输出,然后第四行进入模式空间,并插入空行,依此类推 

    相应的: 
    sed 'n;n;G' 表示在文件的第 3,6,9,12,... 行后面插入一个空行 
    sed 'n;n;n;G' 表示在文件的第 4,8,12,16,... 行后面插入一个空行 
    sed 'n;d' 表示删除文件的偶数行 


    例子四 
    sed '$!N;$!D' 
    输出文件最后2行,相当于 tail -2 foo 

    代码:

    $ cat foo 
    11111111111111 
    22222222222222 
    33333333333333 
    44444444444444 
    55555555555555 

    $ sed '$!N;$!D' foo 
    44444444444444 
    55555555555555 



    解释: 

    D 删除模式空间内第一个 newline 字母 前的资料。 
    N 把输入的下一行添加到模式空间中。 

    sed '$!N;$!D' : 对文件倒数第二行以前的行来说,N 将当前行的下一行放到模式空间中以后,D 就将模式空间的内容删除了;到倒数第二行的时候,将最后一行附加到倒数第二行下面,然后最后一行不执行 D ,所以文件的最后两行都保存下来了。 


    还有 N 的另外一种用法 

    代码:

    $ sed = foo | sed N 

    11111111111111 

    22222222222222 

    33333333333333 

    44444444444444 

    55555555555555 

    $ sed = foo | sed 'N;s/ /   /' 
    1       11111111111111 
    2       22222222222222 
    3       33333333333333 
    4       44444444444444 
    5       55555555555555 


    解释: 
    N 的作用是加上行号,可以用于格式化输出文件 


    例子五 
    sed '1!G;h;$!d' 
    sed -n '1!G;h;$p' 
    将文件的行反序显示,相当于 tac 命令(有些平台没有这个命令) 

    代码:

    $ cat foo 
    11111111111111 
    22222222222222 
    33333333333333 

    $ sed '1!G;h;$!d' foo 
    33333333333333 
    22222222222222 
    11111111111111 

    $ sed -n '1!G;h;$p' foo 
    33333333333333 
    22222222222222 
    11111111111111 



    解释: 
    sed 中 h 用法:h 
    The h (hold) function copies the contents of the pattern space into a holding area, destroying any previous contents of the holding area. 
    意思是将模式空间的内容保存到保持空间中去 

    sed 中的 d 表示删除模式空间。 

    1!G表示除了第一行以外,其余行都执行G命令;$!d表示除了最后一行以外,其余行都执行d命令。 

    看一下sed '1!G;h;$!d'命令执行过程中保持空间与模式空间的变化: 

    命令 保持空间 模式空间 
    第一行 h;d 执行前:null 执行后:1111 执行前:1111 执行后:null 
    第二行 G;h;d 执行前:1111 执行后:2222 1111 执行前:2222 执行后:null 
    第二行 G;h 执行前:22221111 执行后:3333 2222 1111 执行前:3333 执行后:3333 2222 1111  

    (注:把各个行简写了) 

    这样输出以后就是文件的反序了。 

    题外话:在vi中对一个文件进行反序显示的命令是 :g/./m0 , 意思是按照文件正常顺序每找到一行,就把该行放到文件的最上面一行去,这样循环一下正好把文件的行反序显示了。 

    技术链接
  • 相关阅读:
    深入理解Java内存模型(JMM)
    Java基础知识①
    Java自旋锁的几种实现
    ConcurrentHashMap的CAS操作
    Java集合对比总结
    python模块--os模块
    python模块--random
    Datafactory 学习笔记
    Datafactory 实际使用案例
    Oracle三种排名函数使用
  • 原文地址:https://www.cnblogs.com/liujiacai/p/15187476.html
Copyright © 2011-2022 走看看