Is there a way to format numbers as per a precision format in Vi?

I have a log file with a huge list of hexadecimal numbers, I would like to

  1. remove the '0x' prefix; then
  2. make the numbers show up with 8 digit precision (32-bit hex).

For example:

0x12345678 => 12345678
0xABCDF    => 000ABCDF

I need to add those preceding zeros since the output is then used by a diff tool and secondary scripts.


This substitution should do it:

:%s/0x[0-9a-fA-F]*/\=printf('%08X', str2nr(submatch(0), 16))/g

The regex 0x[0-9a-fA-F]* is straightforward, matching hex numbers as you describe.

The replacement string uses an expression, since it starts with \=.

The expression is printf('%08X', str2nr(expand(submatch(0)), 16)), which starts by taking the matched text submatch(0), then converting it to an integer, using base 16 (str2nr(..., 16)) and finally formatting it as an hex string of length (at least) 8, padded with zeroes, using uppercase hex digits for A-F (%08X format string).

The :% makes this match the whole buffer and the /g makes it match multiple hex digits on the same line.

A buffer containing a line with these contents:

0x12345678 0xABCDF

Gets converted to:

12345678 000ABCDF

Which seems to match what you describe.

  • There might be some corner cases not fully covered by this substitution, but you might be able to adapt this to cover your exact use case (for instance, match hex numbers without 0x? what to do with hex numbers with more than 8 digits at the source?). Otherwise, please update the question with more details and I'll update my answer to cover them. – filbranden Sep 12 '18 at 8:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.