Portable one-byte per line hex dump

hexdumpodportability

Suppose we want a minimalist one-byte per line ASCII hex dump. Under Linux using GNU od, this works:

echo foo | od -An -tx1 -w1 -v

Output:

 66
 6f
 6f
 0a

But that won't work with BSD derivatives, because the BSD od util has different flags.

What's the most portable *nix method? Failing that, what are the best available methods?

Best Answer

od is a standard command. In od -An -tx1 -w1 -v, the only thing that is not POSIX is the -w option.

You can replace it with:

od -An -vtx1 | LC_ALL=C tr -cs '0-9a-fA-F' '[\n*]' | grep .

Which would work in any POSIX-compliant system and does work on FreeBSD at least:

$ echo test | od -An -vtx1 | LC_ALL=C tr -cs 0-9a-fA-F '[\n*]' | grep .
74
65
73
74
0a

Or with one sed invocation to replace the tr+grep:

od -An -vtx1 | sed 's/^[[:blank:]]*//;s/[[:blank:]]*$//;/./!d
s/[[:blank:]]\{1,\}/\
/g'

(or

od -An -vtx1 | sed -n 's/[[:blank:]]*\([^[:blank:]]\{2\}\)[[:blank:]]*/\1\
/g;s/\n$//p'

)

With perl (not a POSIX command but ubiquitous on anything but embedded systems):

perl -ne '
  BEGIN{$/ = \8192; $, = $\ = "\n"}
  print  unpack "(H2)*", $_'

Which is also the fastest of the 3 in my tests (compared to GNU od) by a significant margin for anything but small files (also than hexdump, not than vim's xxd).

Related Question