Align a hex text file at 9 bytes each line

This will work regardless of how many bytes are on a single line

sed ':a $!N;s/\n/ /;ta;s/\(\(\([[:xdigit:]]\)\{2\} *\)\{8\}\([[:xdigit:]]\)\{2\}\) */\1\n/g'

Input

$ cat alignbyte
00 2f c6
b8 29 fd 02
37 11 00 9f 74 34 0b 60 72 38
20 00 9e 61 33 8e ab 8a c0 09
00 fa f0 66
6d 0c 44 d6 24
00 a1 11 9d a2 13 a5 b3 83

Output

$ sed ':a $!N;s/\n/ /;ta;s/\(\(\([[:xdigit:]]\)\{2\} *\)\{8\}\([[:xdigit:]]\)\{2\}\) */\1\n/g' alignbyte
00 2f c6 b8 29 fd 02 37 11
00 9f 74 34 0b 60 72 38 20
00 9e 61 33 8e ab 8a c0 09
00 fa f0 66 6d 0c 44 d6 24
00 a1 11 9d a2 13 a5 b3 83

I just noticed that your input file seems to have two blank spaces after each set of 9 bytes, except for the very last set. If that is a typo and all sets of 9 bytes are indeed separated by two spaces then the command to get what you want is simply this:

sed 's/  /\n/g' file

One approach that doesn't care about the exact shape of the input is to split it into one item per line then group items in the desired number.

tr -s '[:space:]' '\n' |
awk '
    NR % 9 != 1 {printf " "}
    {printf "%s", $0}
    NR % 9 == 0 {print ""}
    END {if (NR % 9) print ""}'

If you don't mind an extra space at the end of the line, you can simplify the awk code a bit:

tr -s '[:space:]' '\n' |
awk '
    {printf "%s ", $0}
    NR % 9 == 0 {print ""}
    END {if (NR % 9) print ""}'

If your input has no blank lines and all items are the same width, then there's a simpler solution: put everything on one line then perform line folding.

{ tr -s '\n' ' '; echo; } | fold -w 27

If you have the fmt utility, it can combine both subtasks:

fmt -w 27

Tags:

Python

Bash

Awk

Sed