2012-09-18 137 views
2

我想解析使用bash脚本和sed的s51模拟器的输出。在第一步中,我想要一个包含所有十六进制字节的字符串。模拟器的输出如下所示。实际输出可能会更长,高达64k。解析内存转储(寻找更优雅的解决方案)

0x0000 10 11 12 13 14 15 16 17 ........ 
0x0008 18 19 00 00 00 00 00 00 ........ 
0x0010 00 00 00 00 00 00 00 00 ........ 
0x0018 00 00 00 00 00 00 00 00 ........ 
0x0020 00 00 00 00 00 00 00 00 ........ 
0x0028 00 00 00 00 00 00 00 00 ........ 
0x0030 00 00 00 00 00 00 00 00 ........ 
timer #0("time") ON: 0.001085 sec (13020 clks) 
timer #0("isr") ON,ISR: 0 sec (0 clks) 
timer #0("idle") ON,ISR: 0 sec (0 clks) 

我的代码解析如下:

sed -e ':loop' -e 's/\s\([0-9a-f]\{1\}\)\([0-9a-f]\{1\}\)/\2\1/g' -e 't loop' -n -e 's/.*\(0x[0-9a-f]\{4\}\)\([0-9a-f]\{16\}\).*/\2/p' | sed -e ':a;N;$!ba;s/\n//g' 

第一3份交换每个字节的两个数字和移除的空间。第四部分删除其他行和地址和ASCII表示。最后一部分删除连接线。

此输出一个字符串喜欢这样的:

01112131415161718190000000.... 

我想知道什么我可以做的更好。

+0

是对电流输出COR直接,你只是想简化方法,或者你想获得不同的输出? –

+0

当前输出正确。我只是想简化这个方法。 – mrks

回答

2

这可能会为你工作(GNU SED):

sed '/^0x\S\{4\}\(\(\S\S\)\{8\}\).*/{s//\1/;H};$!d;x;s/\n//g;s/ \(.\)\(.\)/\2\1/g' file 

或(在必要的):

sed -r '/^0x....((..){8}).*/{s//\1/;H};$!d;x;s/\n//g;s/ (.)(.)/\2\1/g' file 
+0

+1但也许可以考虑使用'-r'标志来使事情更优雅/可读?我指的是所有这些逃脱的括号。 – Steve

+0

@steve YWIMC查看编辑 – potong

+0

感谢您的回答。我仍然对以下语句'$!d; x;'有疑问。它是如何工作的? – mrks

2

我认为有以下应该是等价的:

sed -n -e '/^0x[0-9a-f]\{4\}/H' -e '${x;s/\n\S*//g;s/\s\.\.*//g;s/\s\([0-9a-f]\)\([0-9a-f]\)/\2\1/g;p}' 

或者,如果你的sed版本不支持;分离命令:

sed -n -e '/^0x[0-9a-f]\{4\}/H' -e '${x 
s/\n\S*//g 
s/\s\.\.*//g 
s/\s\([0-9a-f]\)\([0-9a-f]\)/\2\1/g 
p 
}' 

这是通过将每个字节行到保留空间,然后当我们到达文件的最后一行时,交换保持和模式空间以一次处理它们。然后,这些步骤是从每行的开头删除换行符和地址,去掉尾随的点(可能实际上并不需要这取决于实际输出),最后交换每个字节的数字并打印。

0

根据您正在运行的Linux版本,有诸如odhexdump这样的工具可以帮助实现此目的。 hexdump甚至带有几分小脚本语言控制多少字节以何种方式得到格式化等高度可配置的......用GNU awk

0

方式一:

awk '/^0x/ { for (i=2; i<=NF; i++) { gsub(/[^0-9]/,"", $i); line=line $i } } END { printf "%s\n", substr(line,2) }' file.txt