2012-03-15 188 views
5

下面您将看到从专有路由设备的32b内存转储中字符串'octeon'的一小段匹配摘录。正如你所看到的,它包含一些调整后的ASCII,从行尾延伸到16个字符,然后是四个32位字(当然每个8个字符),然后是地址偏移量。正则表达式仅匹配行尾的X个字符

000b27a0: 41646a75 7374206f 6374656f 6e5f6970 Adjust octeon_ip 
000b2850: 73740a00 00000000 6f637465 6f6e5f72 st......octeon_r 
000b2870: 5f73697a 65000000 6f637465 6f6e5f72 _size...octeon_r 
000b2990: 6164696e 672e0a00 6f637465 6f6e5f72 ading...octeon_r 
000b29b0: 785f7369 7a650000 6f637465 6f6e5f72 x_size..octeon_r 
000b3050: 780a0000 00000000 6f637465 6f6e5f70 x.......octeon_p 
000b3650: 6564204f 6374656f 6e206d6f 64656c0a ed Octeon model. 
000bade0: 20307825 71780a00 6f637465 6f6e5f6c  0x%qx..octeon_l 
000bafd0: 696e6720 4f637465 6f6e2045 78656375 ing Octeon Execu 
000bd710: 6564204f 6374656f 6e204d6f 64656c21 ed Octeon Model! 
000bd950: 4f435445 4f4e2070 61737320 3120646f OCTEON pass 1 do 
000bda20: 6564206f 6374656f 6e206d6f 64656c3a ed octeon model: 

虽然这一数据包含了一些有用的信息,可悲的是,操作系统(HiveOS)没有试图连续分配内存或合并不同的堆(为什么要?),所以绝大多数的记忆是一个贫瘠的尚未成型的堆。

0004d6b0: 00000000 00000000 00000000 00000000 ................ 
0004d6c0: 00000000 00000000 00000000 00000000 ................ 
0004d6d0: 00000000 00000000 00000000 00000000 ................ 
0004d6e0: 00000000 00000000 00000000 00000000 ................ 
0004d6f0: 00000000 00000000 00000000 00000000 ................ 
0004d700: 00000000 00000000 00000000 00000000 ................ 
0004d710: 00000000 00000000 00000000 00000000 ................ 
0004d720: 00000000 00000000 00000000 00000000 ................ 
0004d730: 00000000 00000000 00000000 00000000 ................ 
0004d740: 00000000 00000000 00000000 00000000 ................ 
0004d750: 00000000 00000000 00000000 00000000 ................ 

我想快速,高效地拔出匹配一些任意的正则表达式模式具有一定规模的字符串([a-zA-z]想到) 你自然会认为运行常年对象转储检查最喜欢的“弦”会产生一个结果,但md util是一个残酷的情妇 - 由于存在ascii编码的十六进制银行&地址,它将每一行标识为包含“字符串”。

当然,我们都知道存在一个简单的脚本解决方案(for line in hexdump: f.write(line[-16:]) + grep '[A-z]' f)。

但是,有时候我会觉得我应该理解这些卑鄙的压迫,但是更好地理解了正则表达式,而不是回到易于使用的新颖编程语言。我真的觉得我无法开始发展真正的Unix领袖,直到我用各种流编辑器和Awk脚本的正则表达式完全替代了我的整个 开发工具链 生活。

如何匹配[a-zA-z]从行尾的一定数量的字符(在我的情况下,16) - 它看起来像一个漂亮精巧的建筑,但+,?的所有组合。 {16}以及在过去几分钟内对我有意义的事情已经及时地失败了。

+0

也许我错误地理解了这个请求。你想获得每行的最后16个字符,或*只从最后16个字符中提取字母*? – TLS 2012-03-15 17:40:53

回答

3

使用“不匹配”开关-v

grep -v \.{16}$ 

这将去掉与16点结束的所有行。

这里的man文档吧:

-v,--invert匹配
反转匹配的意义上说,选择不匹配的行。

3

这是做你想做的吗? “.{16}$

这将匹配行尾的任意16个字符。 $确保它匹配行的末尾。


仔细检查后,如果您想仅提取是不是所有段的线路,你可以使用这个表达式:“{4}(.*?\w.*?)$有前{4},使其之间的分隔符相匹配的空间数字和行的结尾。这在技术上不是“只有16个字符”,但是考虑到数据集,它似乎提供了所需的输出。 (假设所需的输出是任何具有单词字符的行,即字母/数字/下划线。)

+0

你在正确的轨道上,但应用[a-zA-z] {16} $不起作用:( – 2012-03-15 17:49:35

+0

它看起来像你想要一个结果,只要它不是'.......... ......',所以你可以使用负向前视来确保不匹配:'(?![。] {16})。{16} $',它应该与最后16个字符匹配每一行,除非它是一个16个周期的字符串 – VeeArr 2012-03-15 17:59:36

+0

@VeeArr - 我用'(?![。] {16})。{16} $'跑了一个快速测试,但是这似乎仍然会返回所有行 – TLS 2012-03-15 18:08:41

2

过滤有趣行的廉价技巧是用任何字符填充选择直到行尾。在这里,我选择一个不是一个点的字符,并且它不超过从行尾开始的15个字符。(您可以使用POSIX正则表达式,所以你应该写\ {\}与否的重复数量{})

grep '[^.].\{1,15\}$' 

然后你可以管与另一个grep,导致测试,也可以适应的想法,另一个正则表达式:

grep 'abc.\{1,13\}$' 

将mach字符串“abc”放在最后16个字符中。