zoukankan      html  css  js  c++  java
  • sed之h;H和:a;N;ba使用精解(对段落进行操作)

    1)

    文本:
    Handle 0x0058, DMI type 20, 19 bytes
    Memory Device Mapped Address
            Starting Address: 0x0001FFFFC00
            Ending Address: 0x0001FFFFFFF
            Range Size: 1 kB
            Physical Device Handle: 0x0047
            Memory Array Mapped Address Handle: 0x004B
            Partition Row Position: Unknown
            Interleave Position: Unknown
            Interleaved Data Depth: Unknown

    sample 0x0058, DMI type 20, 19 bytes
    Memory Device Mapped Address
            Starting Address: 0x0001FFFFC00
            Ending Address: 0x0001FFFFFFF
            Range Size: 2 kB
            Physical Device Handle: 0x0047
            Memory Array Mapped Address Handle: 0x004B
            Partition Row Position: Unknown
            Interleave Position: Unknown
            Interleaved Data Depth: Unknown

    Handle 0x0058, DMI type 20, 19 bytes
    Memory Device Mapped Address
            Starting Address: 0x0001FFFFC00
            Ending Address: 0x0001FFFFFFF
            Range Size: 3 kB
            Physical Device Handle: 0x0047
            Memory Array Mapped Address Handle: 0x004B
            Partition Row Position: Unknown
            Interleave Position: Unknown
            Interleaved Data Depth: Unknown
    要求:每个段落是Handle开头的就取出Range Size的值:
    1 kB
    3 kB



    1. sed -n '/^Handle/{:a;N;/n$/!{$!ba};s/.*Range Size: ([^n]*).*/1/p}' file
    [解析]
    文本就3个段落,2个空行为分割,用sed首先想到肯定是以空行为分割,把一整段文本读取在一起,然后统一进行匹配和替换,特别注意N读取内容匹配空行是 / $/ ,而不是一般的 /^$/  ,另一个问题是到了尾行因为没有下面的空行来激活,所以我们要在前面加个尾行的匹配跳转。这样就可以成功替换以Handle开头的段落内容,如果没匹配到也当然不会打印。


    1. sed -n 'H;/^$/!{$!b};x;s/nHandle.*Range Size: ([^n]*).*/1/p' file
    [解析]
    因为是以空行为分割,H 追加到 hold space ,后面的替换只对空行或者最后一行才执行,否则都会跳过,也只有符合关键字的才会被替换打印。其他的行则因为 -n 的原因不会被输出。



    最后再附上awk的命令:
    1. awk -vRS= -F" " '/^Handle/{split($5,a,": ");print a[2]}' file



    2)

    文本:
    dn: identifier=1
    objectClass: ZcValidRecord
    DsId: 2
    identifier:2955
    subOptionName: Record
    SvcId: 1
    ZoneId: 0

    dn: identifier=2
    objectClass: ZcValidRecord
    DsId: 2
    identifier:2956
    subOptionName: Record
    SvcId: 2
    ZoneId: 0

    要求后面的数字替换前面的数字:
    dn: identifier=2955
    objectClass: ZcValidRecord
    DsId: 2
    identifier:2955
    subOptionName: Record
    SvcId: 1
    ZoneId: 0

    dn: identifier=2956
    objectClass: ZcValidRecord
    DsId: 2
    identifier:2956
    subOptionName: Record
    SvcId: 2
    ZoneId: 0



    1. sed ':a;N;/n$/!{$!ba};s/([^0-9]*)[0-9]*(.*identifier:)([0-9]*)/1323/' file
    [解析]
    初一看这题觉得不难,就是简单的数字替换,关键就在于数字的位置,我们都知道不管是shell还是awk还是sed,它都是逐行执行的,换句话说,执行到后面的行后,就不可能再对前面的行进行修改,这个跟我们往常的前面匹配修改后面的内容不一样,这里我们利用sed,把内容统一读取后,用正则来匹配修改它。这里还有另外两个要点,第一,文本是以空行为段落分割,在N读取模式中匹配空行不能再是传统的 /^$/ ,而是 / $/ ,这点上特别注意,第二,针对空行触发条件,到了文件末尾时,没有空行来触发,所以要依据文件末行来触发替换,这里就有了两个标签跳转。



    1. sed -n '1h;/^$/!{1!H;$!b};x;s/([^0-9]*)[0-9]*(.*identifier:)([0-9]*)/1323/p' file
    [解析]
    这是 h;H 的搭配;道理也是一样把一个段落读入 hold space 里,再出发条件统一替换。

  • 相关阅读:
    数据库01 /Mysql初识、基本指令、数据库密码相关、创建用户及授权
    数据库/MySQL的安装
    Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程
    Python并发编程05 /死锁现象、递归锁、信号量、GIL锁、计算密集型/IO密集型效率验证、进程池/线程池
    Python并发编程04 /多线程、生产消费者模型、线程进程对比、线程的方法、线程join、守护线程、线程互斥锁
    Python并发编程03 /僵孤进程,孤儿进程、进程互斥锁,进程队列、进程之间的通信
    python并发编程02 /多进程、进程的创建、进程PID、join方法、进程对象属性、守护进程
    Python并发编程01 /操作系统发展史、多进程理论
    java继承内部类问题(java编程思想笔记)
    递归遍历文件夹中的文件
  • 原文地址:https://www.cnblogs.com/xialiaoliao0911/p/7524031.html
Copyright © 2011-2022 走看看