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 部分交换每个字节的两位数并删除空格。第 4 部分删除了其他行以及地址和 ascii 表示。最后一部分删除了连接线。

这会输出一个像这样的字符串:

01112131415161718190000000....

我想知道我可以做得更好。

4

4 回答 4

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
}'

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

于 2012-09-18T18:02:30.050 回答
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
于 2012-09-19T06:16:35.330 回答
0

根据您运行的 Linux 版本,有类似odhexdump可以帮助解决此问题的工具。hexdump甚至可以使用一种迷你脚本语言进行高度可配置,以控制以何种方式格式化多少字节等等......

于 2012-09-18T20:43:34.497 回答
0

一种使用方式GNU awk

awk '/^0x/ { for (i=2; i<=NF; i++) { gsub(/[^0-9]/,"", $i); line=line $i } } END { printf "%s\n", substr(line,2) }' file.txt
于 2012-09-18T23:24:56.387 回答