2012-09-18 134 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