假設我產生了兩個十六進位轉儲,其中包括星號。第一份文件(xxd -r
作品):
hexdump random.dat
0000000 6161 6161 6161 6161 6161 6161 6161 6161
*
0000020 6161 6261 6262 6262 6262 6262 6262 6262
0000030 6262 6262 6262 6262 6262 6262 6262 6262
*
00000b0
第二個文件(xxd -r
不起作用):
hexdump data2.dat
0000000 6161 6161 6161 6161 6161 6161 6161 6161
*
0000020 6161 6261 6262 6262 6262 6262 6262 6262
0000030 6262 6262 6262 6262 6262 6262 6262 6262
*
00000b0 000a
00000b1
希望能夠在沒有壓縮的情況下產生原始轉儲,並且沒有原始檔案。正是這樣:
hexdump -v random.dat
0000000 6161 6161 6161 6161 6161 6161 6161 6161
0000010 6161 6161 6161 6161 6161 6161 6161 6161
0000020 6161 6261 6262 6262 6262 6262 6262 6262
0000030 6262 6262 6262 6262 6262 6262 6262 6262
0000040 6262 6262 6262 6262 6262 6262 6262 6262
0000050 6262 6262 6262 6262 6262 6262 6262 6262
0000060 6262 6262 6262 6262 6262 6262 6262 6262
0000070 6262 6262 6262 6262 6262 6262 6262 6262
0000080 6262 6262 6262 6262 6262 6262 6262 6262
0000090 6262 6262 6262 6262 6262 6262 6262 6262
00000a0 6262 6262 6262 6262 6262 6262 6262 6262
00000b0
hexdump -v data2.dat
0000000 6161 6161 6161 6161 6161 6161 6161 6161
0000010 6161 6161 6161 6161 6161 6161 6161 6161
0000020 6161 6261 6262 6262 6262 6262 6262 6262
0000030 6262 6262 6262 6262 6262 6262 6262 6262
0000040 6262 6262 6262 6262 6262 6262 6262 6262
0000050 6262 6262 6262 6262 6262 6262 6262 6262
0000060 6262 6262 6262 6262 6262 6262 6262 6262
0000070 6262 6262 6262 6262 6262 6262 6262 6262
0000080 6262 6262 6262 6262 6262 6262 6262 6262
0000090 6262 6262 6262 6262 6262 6262 6262 6262
00000a0 6262 6262 6262 6262 6262 6262 6262 6262
00000b0 000a
00000b1
所以程序是:
- 從檔案(或從標準輸入)讀取轉儲。
- 對於每個星號:
- 讀取下一行開始處的結束偏移量。
- 讀取上一行開頭處的起始偏移量。
- 讓它們休息以確定需要插入多少行。
- 插入那麼多行,偏移量相應增加。
- 將整個轉儲輸出到另一個檔案或標準輸出。
答案1
嘗試
awk '
/^\*/ {GAP = 1 # check if action needed
next # don''t print, proceed to next line
}
GAP {TGT = sprintf ("%d", "0x" $1) + 0 # if action, calculate the end target
do {printf "%07x %s\n", L1, L0 # loop printing identical lines
L1 += 16 # increment the first field
}
while (TGT > L1) # until target reached
GAP = 0 # reset action flag
}
{L1 = sprintf ("%d", "0x" $1) + 16 # save "to come" first field
L0 = $0 # and rest of line
sub ("^" $1 FS, _, L0)
}
1 # print input line
' file2
0000000 6161 6161 6161 6161 6161 6161 6161 6161
0000010 6161 6161 6161 6161 6161 6161 6161 6161
0000020 6161 6261 6262 6262 6262 6262 6262 6262
0000030 6262 6262 6262 6262 6262 6262 6262 6262
0000040 6262 6262 6262 6262 6262 6262 6262 6262
0000050 6262 6262 6262 6262 6262 6262 6262 6262
0000060 6262 6262 6262 6262 6262 6262 6262 6262
0000070 6262 6262 6262 6262 6262 6262 6262 6262
0000080 6262 6262 6262 6262 6262 6262 6262 6262
0000090 6262 6262 6262 6262 6262 6262 6262 6262
00000a0 6262 6262 6262 6262 6262 6262 6262 6262
00000b0 000a
00000b1
答案2
@RudiC 非常感謝。您的腳本適用於awk
( original-awk
) 和mawk
,但不適用於gawk
.事先檢查一下是哪個開發者以及版本是什麼。您也可以使用namei /usr/bin/awk
.某些 linux 發行版 / *BSD 可能包含它的任何版本,並且是任何其他發行版的符號連結。
很多時候,「awk」只是 gawk、original-awk 或 mawk 的符號連結。
hexdump.exe random.dat | gawk '
/^\*/ {GAP = 1 # check if action needed
next # don''t print, proceed to next line
}
GAP {TGT = sprintf ("%d", "0x" $1) + 0 # if action, calculate the end target
do {printf "%07x %s\n", L1, L0 # loop printing identical lines
L1 += 16 # increment the first field
}
while (TGT > L1) # until target reached
GAP = 0 # reset action flag
}
{L1 = sprintf ("%d", "0x" $1) + 16 # save "to come" first field
L0 = $0 # and rest of line
sub ("^" $1 FS, _, L0)
}
1 # print input line
'
0000000 6161 6161 6161 6161 6161 6161 6161 6161
0000010 6161 6161 6161 6161 6161 6161 6161 6161
0000020 6161 6261 6262 6262 6262 6262 6262 6262
0000030 6262 6262 6262 6262 6262 6262 6262 6262
0000010 6262 6262 6262 6262 6262 6262 6262 6262
00000b0
hexdump.exe data2.dat | gawk '
> /^\*/ {GAP = 1 # check if action needed
> next # don''t print, proceed to next line
> }
> GAP {TGT = sprintf ("%d", "0x" $1) + 0 # if action, calculate the end target
> do {printf "%07x %s\n", L1, L0 # loop printing identical lines
> L1 += 16 # increment the first field
> }
> while (TGT > L1) # until target reached
> GAP = 0 # reset action flag
> }
> {L1 = sprintf ("%d", "0x" $1) + 16 # save "to come" first field
> L0 = $0 # and rest of line
> sub ("^" $1 FS, _, L0)
> }
> 1 # print input line
> '
0000000 6161 6161 6161 6161 6161 6161 6161 6161
0000010 6161 6161 6161 6161 6161 6161 6161 6161
0000020 6161 6261 6262 6262 6262 6262 6262 6262
0000030 6262 6262 6262 6262 6262 6262 6262 6262
0000010 6262 6262 6262 6262 6262 6262 6262 6262
00000b0 000a
00000b1