I've a long hex string 00121eafc5800020 ... etc.

Is there an easy way I can split these with a space per hex coded byte so I get 00 12 1e af c5 80 00 20 in vim (or another easily accessible tool)

4 Answers 4

$ sed 's/\(..\)/\1 /g' <<< '1234567890'
12 34 56 78 90 
  • Same command works in vim too, just add a line number, a range, or a % in front of it as appropriate. (Uh, I'll mention that you should remove the 'sed' bit... just in case, I've seen some impressive people here.)
    – lornix
    Oct 21, 2011 at 11:18
  • 2
    Which is equivalent to s/../& /g Oct 21, 2011 at 12:42
  • note that the /g at the end will dice up everything on the given line. Nov 2, 2011 at 2:46
  • How does that regular expression work? Nov 19, 2011 at 19:51
  • It puts 2 characters in group 1, then outputs group 1 with a space after it. Nov 19, 2011 at 20:23

Try this key sequence (from the start of the number): q1lxPpr lq@1@1@1@1@1@1@1@1 (etc. or say, 20@1)

  • "Try this key sequence" without any explanation is never a good answer to vim questions. Oct 21, 2011 at 12:43
  • Maybe. But that would spoil the fun of finding out.
    – Benedict
    Oct 21, 2011 at 12:54
  • 1
    Last I checked, this site was where people went for good answers. Oct 21, 2011 at 12:56
  • 1
    I agree. This is a good answer. You'll note the (also good) accepted answer is also pretty terse. If you want to edit both to add a wordy explanation you are welcome to. Alternatively you can trust that the average reader knows enough to lookup the details to sed regex or the vim key map.
    – Benedict
    Oct 21, 2011 at 13:06

In vim, you can use :s/\([0-9a-f][0-9a-f]\)/\1 /g to do what you want. To test this, you can use the following command:

dd bs=512 if=/dev/urandom count=2 2>/dev/null | xxd -p | tr -d '\n' | vim -

Then in vim, use :s/\([0-9a-f][0-9a-f]\)/\1 /g to add a space after every pair of hex-characters. Here's a small example:

$ dd bs=32 if=/dev/urandom count=1 2>/dev/null | xxd -p | tr -d '\n' | vim -
:s/\([0-9a-f][0-9a-f]\)/\1 /g
6a ad 5f 80 0a 73 9f ad bc 3e 23 12 23 0d ae ca 80 55 49 15 77 b0 e0 d7 5a 37 bb 37 77 f0 a3 e0 
:%s/\x\x/& /g

is enough.

If you want to cut into several lines, you can also apply this :substitute first.


Or if you prefer a one-liner (I'm not sure this is a better solution here)

:%s/\x\{16}/\=substitute(submatch(0), '\x\x', '& ', 'g')."\n"/g

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .