• 文本处理三剑客之 Sed ——高级编辑命令


    本篇介绍sed的高级编辑命令


    高级编辑命令

    P:打印模式空间开端至 内容,并追加到默认输出之前

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

    N:读取匹配到的行的下一行追加至模式空间

    h: 把模式空间中的内容覆盖至保持空间中

    H:把模式空间中的内容追加至保持空间中

    g: 从保持空间取出数据覆盖至模式空间

    G:从保持空间取出内容追加至模式空间

    x: 把模式空间中的内容与保持空间中的内容进行互换

    d: 删除模式空间中的行,并进入下一个循环

    D: 删除当前模式空间开端至 的内容,放弃之后的命令,之后对模式空间剩余内容重新执行前面的命令,如果模式空间没有 ,则与d相同(之后会有详细说明)


    关于多行:

    被追加了行的空间,里面的内容被sed看做是被 隔开的行:

    如:

    模式空间原有的行 被追加的行


    p/P命令:

    都用于打印模式空间内容,两者区别:

    小写p打印当前模式空间内容,追加到默认输出之后

    大写P打印当前模式空间开始至 的内容,并追加到默认输出之前。


    n命令:

    读取下一行,覆盖模式空间的前一行,如果期间任何命令执行失败,则停止运行后续命令.


    示例:

    文件text的内容如下

    1a

    2b

    3c

    4d

    5e

    6f

    7g

    8h

    9i

    取出文件中的偶数行

    $ sed -n 'n;p' text
    2b
    4d
    6f
    8h
    

    解析:

    读取第一行1a,执行n命令,此时模式空间为2b,执行p,打印模式空间内容2p

    读取第三行3c,执行n命令,此时模式空间为4d,执行p,打印模式空间内容4d

    读取第五行5e,执行n命令,此时模式空间为6f,执行p,打印模式空间内容6f

    读取第七行7g,执行n命令,此时模式空间为8h,执行p,打印模式空间内容8h

    读取第九行9i,执行n命令,由于没有下一行,n命令执行失败,所以直接退出,不执行后续p命令.

    所以最后输出结果即为全部偶数行


    N命令:

    读取并将下一行追加到模式空间,但把两行看做是含有 换行符的一行,如果期间任何命令执行失败,则停止运行后续命令.

    示例:

    文件text的内容如下

    1a

    2b

    3c

    4d

    5e

    6f

    7g

    8h

    9i

    取出文件中的奇数行

    $ sed -n '$!N;P' text  # -n 不显示默认输出
    1a
    3c
    5e
    7g
    9i
    

    解析:

    读取第一行1a,不是最后一行,$!条件成立,执行N,取出下一行内容2b追加到1a之后,此时模式空间为1a 2b,执行P,仅输出 前内容,即1a

    读取第三行3c,不是最后一行,$!条件成立,执行N,取出下一行内容4d追加到3c之后,此时模式空间为3c 4d,执行P,仅输出 前内容,即3c

    读取第五行5e,不是最后一行,$!条件成立,执行N,取出下一行内容6f追加到5e之后,此时模式空间为5e 6f,执行P,仅输出 前内容,即5e

    读取第七行7g,不是最后一行,$!条件成立,执行N,取出下一行内容8h追加到7g之后,此时模式空间为7g 8h,执行P,仅输出 前内容,即7g

    读取第九行9i,因为最后一行,$!条件不成立,跳过执行N,直接执行P,即输出9i.

    所以最后输出结果为全部奇数行.

    注意匹配失败也是命令执行成功的一种结果,并非命令执行失败.


    d命令:

    删除模式空间的所有内容,并直接进入下一个循环.

    示例:

    文件text的内容如下

    1a

    2b

    3c

    4d

    5e

    6f

    7g

    8h

    9i

    取出文件中的奇数行

    $ sed 'n;d' text
    1a
    3c
    5e
    7g
    9i
    

    解析:

    读取第一行1a,执行命令n,此时模式空间内容为2b,执行d,模式空间清空,最后默认输出为没有被处理过的1a

    读取第三行3c,执行命令n,模式空间为4d,执行d,模式空间空,默认输出3c

    第五行....5e

    第七行....7g

    第九行9i,由于没有下一行,n执行失败,终止后续命令.默认输出9i

    所以最终输出结果为所有奇数行


    D命令:

    删除模式空间开始到第一个 的所有内容,结束后续命令,并使用模式空间剩余内容进入下一轮循环.

    示例:

    文件text的内容如下

    1a

    2b

    3c

    4d

    5e

    6f

    7g

    8h

    9i

    取文件最后一行

    $ sed 'N;D' text
    9i
    

    解析:

    读取第一行1a,执行N,模式空间内容为1a 2b,执行D,模式空间剩下2b.

    返回执行N,取出第三行3c,模式空间为2b 3c,执行D,模式空间为3c

    ......

    返回执行N,取出第九行9i,模式空间为8h 9i,执行D,模式空间为9i

    返回执行N,没有下一行,执行失败,不执行后续命令,默认输出模式空间内容9i.

    最终输出结果为最后一行


    H/G/h/g命令:

    大写的H/G都为追加操作

    H为模式空间追加到保持空间

    G为保持空间追加到模式空间


    小写的h/g都是覆盖操作

    h为模式空间覆盖保持空间

    g为保持空间覆盖模式空间


    示例:

    $ sed 'G' text #文件每一行之后插入空行
    1a
    
    2b
    
    3c
    
    4d
    
    5e
    
    6f
    
    7g
    
    8h
    
    9i
    

    解析:

    保持空间是空,所以G追加到模式空间也就是空行了.


    $ sed 'g' text #结果为9个空行

    解析:

    保持空间是空,把模式空间每一行都覆盖为空.


    $ sed '1!G;$!h;$!d' text #逆序显示文件的行
    9i
    8h
    7g
    6f
    5e
    4d
    3c
    2b
    1a
    

    解析:

    读取第一行1a,1!条件不成立,跳过G,执行h,模式空间中的1a覆盖到保持空间,$!成立执行d,删除模式空间内容,进入下个循环

    读取第二行2b,1!条件成立,执行G,模式空间变为2b 1a,执行h,覆盖到保持空间,$!成立,执行d,删除模式空间内容,进入下个循环

    读取第三行3c,1!条件成立,执行G,模式空间变为3c 2b 1a,执行h,覆盖到保持空间,$!成立,执行d,删除模式空间内容,进入下个循环

    ....

    读取最后一行9i,1!条件成立,执行G,模式空间变为9i 8h 7g 6f 5e 4d 3c 2b 1a,$!成立,跳过h,跳过d,默认输出模式空间内容.9i 8h 7g 6f 5e 4d 3c 2b 1a


    其他示例:

    使用含有模式的文件,将文件中的小写字母转换成大写,并将每一行的字母与数字交换位置

    文件text的内容为

    1a

    2b

    3c

    4d

    5e

    6f

    7g

    8h

    9i

    $ cat pat
    h
    y/abcdefghi/ABCDEFGHI/
    s@([0-9])([A-Z])@21@
    
    $ sed -rf pat text # -r 使用扩展正则,-f 指定含有模式的文件
    A1
    B2
    C3
    D4
    E5
    F6
    G7
    H8
    I9
    

    解析

    第一步读取一行执行h,放入保持空间.

    第二步把所有小写字母换成大写

    第三步通过替换命令把字母和数字位置调换


    文本number.txt中内容如下

    $ cat numbers.txt 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    

    将文本文件的n和n+1行合并为一行,n为奇数行

    $ sed 'N;s@
    @ @g' number.txt
    1 2
    3 4
    5 6
    7 8
    9
    

    解析:

    读取第一行1,放入模式空间,执行N,模式空间为1 2,执行s替换 为空格,结果为1 2,默认输出1 2

    读取第三行3,放入模式空间,执行N,模式空间为3 4,执行s替换 为空格,结果为3 4,默认输出3 4

    .....

    读取第九行9,执行N失败,不执行后续命令,默认输出9


    每两行为一组倒序排列

    $ seq 1 8 | sed -n '$!N;2!G;h;$p'
    7
    8
    5
    6
    3
    4
    1
    2
    

    解析:

    seq 结果为

    1

    2

    3

    4

    5

    6

    7

    8

    读取第一行,$!成立,执行N,读取第二行内容追加到模式空间,模式空间为1 2,因为已经读取到第2行,所以2!不成立,跳过G,执行h,保持空间为1 2,不是最后一行,$不成立,不执行p不输出到屏幕

    读取第三行,$!成立,执行N,读取第四行内容追加到模式空间,模式空间为3 4,2!成立,执行G,把保持空间的1 2追加到模式空间,此时模式空间为3 4 1 2,执行h,覆盖到保持空间,再次跳过p输出

    .........

    读取第七行,$!成立,执行N,读取第八行内容追加到模式空间,模式空间为7 8,2!成立,执行G,把保持空间的5 6 3 4 1 2到模式空间,此时模式空间为7 8 5 6 3 4 1 2,执行h,覆盖到保持间,这一步是多于的,可以在h前加$!跳过此步,最后因为是最后一行$成立,p成功执行,打印模式空间内容

  • 相关阅读:
    【由浅入深理解java集合】(四)——集合 Queue
    【由浅入深理解java集合】(三)——集合 List
    Java根类Object的方法说明
    【由浅入深理解java集合】(二)——集合 Set
    【由浅入深理解java集合】(一)——集合框架 Collction、Map
    HTTP Content-type 对照表
    ADB Not Responding
    CString 成员函数用法大全
    Oracle中关于DateTime的一些描述
    常用html、CSS、javascript前端命名规范
  • 原文地址:https://www.cnblogs.com/Q--T/p/7967453.html
Copyright © 2020-2023  润新知