3

I have a space-separated .txt file of numbers:

40.766375 -84.267443
40.766355 -84.267463
40.766325 -84.263443
...

Occasionally, there is a number in the first column that does not have 6 digits after the decimal:

40.76632 -84.263443

I want to insert a 0 at the end of each such occurrence, so that I end up with:

40.766320 -84.263443

There are many rows (over 36000), so I'd like to do this with regex. Any ideas?

EDIT: I think I need something like :%s/\.d{5}/\.d{5}0 but I can't quite get there.

1
:%s/\(\.\d\{5\}\) /\10 /

This can do what you want.

Explanation

With \(\.\d{5\}\) we capture first occurrence of dot (\.) and five digits (\d\{5\}). Also, we checks that there are exactly five of them by leaving the space after capture group.

In the second part of substitution, we're using \1 to get access to the first (and once) capture group, put 0 after it and put a space to the end, because the space was matched by regexp, but didn't transfered to second part.

A bit about the capture groups: \10 is exactly «capture group number one and zero after it». Thus, you can get access to only eight groups.

  • But if it isn't necessary to do it exactly with vim, i can update this solution with using sed. Probably, regexp will become easier, and using it is simpler than running vim and doing it. – ValeriyKr Feb 28 '17 at 14:23
  • It worked! Thanks @ValeriyKr. What does the /\10 / mean? – StatsSorceress Feb 28 '17 at 14:24
  • \(regexp\) is a capture group. You can access to them with \N, where N is its number (from left to right). Here i'm capturing dot and five digits, leaving space outside. – ValeriyKr Feb 28 '17 at 14:31
0

As a more general way to force all numbers to have 6 digit after the period, you could do:

:%s/\.\d\+/&00000/g
:%s/\.\d\{6}\zs\d*//g

The first one adds 5 zeros, and the second one removes all but the first 6 digits after the period. \zs is vim's equivalent of perl's \K that resets the start of the matched portion.

You can also do things like:

 :%s/\d\+\.\d\+/\=printf("%.6f", str2float(submatch(0)))/g

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.