# Precision format in Vi

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