zoukankan      html  css  js  c++  java
  • sed 模式空间 保持空间

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

    正常情况下,如果不显示使用某些高级命令,保持空间不会使用到!

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

     

    一般情况下,数据的处理只使用模式空间(pattern space),按照如上的逻辑即可完成主要任务。但是某些时候,通过使用保持空间(hold space),还可以带来意想不到的效果。

    命令含义:

    h,将当前模式空间中的内容覆盖到 保持空间中,

    n,用于提前读取下一行,并且覆盖当前模式空间中的这一行

    H,将当前模式空间中的内容追加到 保持空间 中

    x,交换模式空间和保持空间中的内容

    g,将保持空间中的内容拷贝到模式空间中,原来模式空间里的内容清除。

    d,删除模式空间中的所有行,并读入下一新行到模式空间中。
    D,删除multiline pattern中的第一行,不读入下一行。


    通过几个例子看sed的模式空间和保持空间
    例子一
    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' 对于KSH则为 sed '/^ *$/d'

    例子二
    sed '/regex/{x;p;x;}'
    在匹配regex的任何行前面插入一个空行
    代码:
    $ cat foo
    11111111111111
    22222222222222
    test33333333333
    44444444444444
    55555555555555

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

    test33333333333
    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 的作用是把模式空间复制到标准输出。
    分析一下该命令执行过程中保持空间和模式空间的内容
    命令 保持空间 (holdspace) 模式空间(patternspace)
    x 执行前:null 执行后:test...$ 执行前:test...$ 执行后:null
    p 执行前:null 执行后:test...$ 执行前:test...$ 执行后:null 输出一个空行
    x 执行前:test...$ 执行后:null 执行前:null 执行后:test...$
    个人觉得上面的命令执行分析有点问题,我的分析如下:
    命令 模式空间(patternspace) 保持空间 (holdspace)
    x 执行前:test...$ 执行后:null 执行前:null 执行后:test...$
    p 执行前:null 执行后:null但输出一空行 执行前:test...$ 执行后:test...$
    x 执行前:null 执行后:test...$ 执行前:test...$ 执行后:null
    引申:能够试验一下 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 前的资料。
    N 把输入的下一行添加到模式空间中。
    sed '$!N;$!D' : 对文档倒数第二行以前的行来说,N 将当前行的下一行放到模式空间中以后,D 就将模式空间的内容删除了(补充一点:D是将模式空间的的第一行删除);(循环删除到模式空间里只剩下倒数第二行时)到倒数第二行的时候,将最后一行附加到倒数第二行下面,然后最后一行不执行 D ,所以文档的最后两行都保存下来了。
    更有 N 的另外一种用法代码:
    $ sed = foo | sed N (一定要这样的命令格式)
    1
    11111111111111
    2
    22222222222222
    3
    33333333333333
    4
    44444444444444
    5
    55555555555555
    $ sed = foo | sed 'N;s//n/ /'
    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 执行后:11..$ 执行前:11..$ 执行后:null
    第二行 G;h;d 执行前:11..$ 执行后:22..$/n11..$ 执行前:22..$ 执行后:null
    第二行 G;h 执行前:22..$/n11..$执行后:33..$/n22..$/n11..$ 执行前:33..$ 执行后:33..$/n22..$/n11..$
    这样输出以后就是文档的反序了。

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

    参考http://www.xuebuyuan.com/951950.html

    http://blog.csdn.net/wanglelelihuanhuan/article/details/51591809

  • 相关阅读:
    URL传参数导致乱码
    [转载]HTTP协议详解
    https中关于密码学的基础概念
    JavaScript高级程序设计 第四章 变量、作用域和内存问题
    JavaScript高级程序设计 第三章 基本概念
    实现sticky footer的五种方法
    css grid学习材料整理
    ASP.NET MVC编程——视图
    Entity Framework——配置文件设置
    Entity Framework——记录执行的命令信息
  • 原文地址:https://www.cnblogs.com/fanren224/p/8476603.html
Copyright © 2011-2022 走看看