Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3031785
  • 博文数量: 272
  • 博客积分: 5544
  • 博客等级: 大校
  • 技术积分: 5496
  • 用 户 组: 普通用户
  • 注册时间: 2011-03-08 00:48
个人简介

  每个人都要有一个骨灰级的爱好,不为金钱,而纯粹是为了在这个领域享受追寻真理的快乐。

文章分类

全部博文(272)

文章存档

2015年(2)

2014年(5)

2013年(25)

2012年(58)

2011年(182)

分类: LINUX

2011-10-30 19:48:54

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



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

阅读(9874) | 评论(0) | 转发(2) |
给主人留下些什么吧!~~