0

Say I've generated two hexdump, which include the asterisk. First file (xxd -r works):

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

Second file (xxd -r doesn't work):

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

Would like to be able to generate the original dump without the squeezing, and without having the original file. Exactly like this:

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

So the procedure would be:

  1. Read dump from file (or from stdin).
  2. For each asterisk:
    • Read ending offset at start of next line.
    • Read starting offset at start of previous line.
    • Rest them to determine how many lines require to be inserted.
    • Insert that many lines, with the offset being increasing as corresponding.
  3. Output the entire dump to another file or stdout.
  • - Please, edit your question and show us what you tried so far. – andcoz Apr 6 at 15:58
  • It seems like xxd -r can read the elided version - so maybe one option would be regenerate the binary data - then you can generate the dump in whatever alternate format you wish – steeldriver Apr 6 at 16:07
  • @andcoz @steeldriver I've added second example where xxd -r doesn't work. If you use shortcuts you risk introducing a bug in the system, which you've just done. – Smeterlink Apr 6 at 17:44
2

Try

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
| improve this answer | |
1

@RudiC Thanks a lot. Your script works with awk (original-awk) and mawk, but not with gawk. Check beforehand which one is the developer and whose version it is. You can also use namei /usr/bin/awk. Certain linux distros / *BSD may include any version of it and be a symlink to any other.

A lot of times, 'awk' is just a symlink to gawk, original-awk or 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
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.