in reply to Re: hexdump -C
in thread hexdump -C

Actually it was solving the problem that the run of \0 lines needs to be replaced by a single '*', not one '*' per every 16 zeroes.

But, as I went to create an example for you, I realized I misunderstood the '*' behavior. It prints one full line of 00 00 00 ... and then the '*' means "repeat the previous line". I'd only ever seen it replace zeroes with '*' because that's the most likely repetition to appear in data files.

$ perl -E 'say "\0"x64 ."A"x64' | hexdump -C 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |......... +.......| * 00000040 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 41 |AAAAAAAAA +AAAAAAA| * 00000080 0a |.| 00000081

Combining everyone's ideas, I now get:

sub hexdump($data) { $data =~ s/\G(.{1,16})(\1+)?/ sprintf "%08X %-50s|%s|\n%s", $-[0], "@{[unpack q{(H2)8a0(H2)8},$1]}", $1 =~ y{ -~}{.}cr, "*\n"x!!$+[2] /segr . sprintf "%08X", $+[0] }

Replies are listed 'Best First'.
Re^3: hexdump -C
by harangzsolt33 (Deacon) on Oct 15, 2025 at 14:07 UTC
    That is so cool! I modified it slightly so it also runs on TinyPerl 5.8:

    sub hexdump { my $s; $_[0] =~ s/\G([\0-\xff]{1,16})/ $s = $1; $s =~ y|\x20-\x7e|.|c; spri +ntf("%08X %-50s|%s|\n", $-[0], "@{[unpack q{(H2)8a0(H2)8}, $1]}", $s +);/ge; return $_[0]; }

    I don't understand why I had to do this: ([\0-\xff]{1,16}) instead of (.{16}) This latter one won't capture anything, which is weird. The second thing I don't understand is why this works:

    "@{[unpack q{(H2)8a0(H2)8}, $1]}"

      Maybe cause you were missing the /s? (It was also missing in the original code.)

      a0 returns a zero-length string. [ ] creates an anon array and returns a reference to is. @{ ... } is the referenced array. Interpolating an array in a string joins elements with spaces by default.

        Hmm... interesting! oh yes yes yes, I forgot the /s

        So, once again, here is the working code:

        #!/usr/bin/perl -w use strict; use warnings; @ARGV = ($0); print hexdump( join('', <>) ); sub hexdump { my $s; $_[0] =~ s/\G(.{1,16})/ $s = $1; $s =~ y|\x20-\x7e|.|c; sprintf("%08 +X %-50s|%s|\n", $-[0], "@{[unpack q{(H2)8a0(H2)8}, $1]}", $s);/ges; return $_[0]; }