Shell magic wanted: format output of hexdump in a pipe
-
12-11-2019 - |
Question
I'm debugging the output of a program that transmits data via TCP.
For debugging purposes i've replaced the receiving program with netcat
and hexdump
:
netcat -l -p 1234 | hexdump -C
That outputs all data as a nice hexdump, almost like I want. Now the data is transmitted in fixed blocks which lengths are not multiples of 16, leading to shifted lines in the output that make spotting differences a bit difficult:
00000000 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |P...............|
00000010 00 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |.P..............|
00000020 00 00 50 00 00 00 00 00 00 00 00 00 00 00 00 00 |..P.............|
How do I reformat the output so that after 17 bytes a new line is started? It should look something like this:
50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |P...............|
00 |. |
50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |P...............|
00 |. |
50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |P...............|
00 |. |
Using hexdumps -n
parameter does not work since it will exit after reaching the number of bytes. (Unless there is a way to keep the netcat programm running and seamlessly piping the next bytes to a new instance of hexdump).
Also it would be great if I could use watch -d
on the output to get a highlight of changes between lines.
Solution
For hexdump without characters part.
hexdump -e '16/1 "%0.2x " "\n" 1/1 "%0.2x " "\n"'
OTHER TIPS
I use this:
use strict;
use warnings;
use bytes;
my $N = $ARGV[0];
$/ = \$N;
while (<STDIN>) {
my @bytes = unpack("C*", $_);
my $clean = $_;
$clean =~ s/[[:^print:]]/./g;
print join(' ', map {sprintf("%2x", $_)} @bytes),
" |", $clean, "|\n";
}
Run it as perl scriptname.pl N
where N is the number of bytes in each chunk you want.
also you can use xxd -p
to make a hexdump .