Question

I know this is a long shot, but I have a huge text file and I need to add a given number to other numbers matching some criteria.

Eg.

identifying text 1.1200
identifying text 1.1400

and I'd like to transform this (by adding say 1.15) to

identifying text 2.2700
identifying text 2.2900

Normally I'd do this in Python, but it's on a Windows machine where I can't install too many things. I've got Vim though :)

Was it helpful?

Solution

Here is a simplification and a fix on hobbs' solution:

:%s/identifying text \zs\d\+\(.\d\+\)\=/\=(1.15+str2float(submatch(0)))/

Thanks to \zs, there is no need to recall the leading text. Thanks to str2float() a single addition is done on the whole number (in other words, 1.15 + 2.87 will give the expected result, 4.02, and not 3.102).

Of course this solution requires a recent version of Vim (7.3?)

OTHER TIPS

You can do a capturing regex and then use a vimscript expression as a replacement, something like

:%s/\(identifying text \)\(\d\+\)\.\(\d\+\)/
  \=submatch(1) . (submatch(2) + 1) . "." . (submatch(3) + 1500)

(only without the linebreak).

Your number format seems to be a fixed one, so it's easy to convert to int and come back (remove the dot) add 11500 and put the dot back.

:%s/\.//
:%normal11500^A " type C-V then C-a
:%s/....$/.&/

If you don't want to do that on all the lines but only the one which match 'identifying text' replace all the % by 'g/indentifying text/'

For integers you can just use n^A to add n to a number (and n^X to subtract it). I doubt whether that works for fractional numbers though.

Well this might not be a solution for vim but I think awk can help:

cat testscript | LC_ALL=C awk '{printf "%s %s %s %s %.3f\n", $1,$2,$3,$4,$5+1.567   }'

and the test

this is a number 1.56
this is a number 2.56
this is a number 3.56

I needed the LC_ALL=C for the correct conversion of the floating point separator, and maybe there is a more elegant solution for printing the beginning/ rest of the string. And the result looks like:

this is a number 3.127
this is a number 4.127
this is a number 5.127

Using macro

qa .......................... start record macro 'a'
/iden<Enter> ................ search 'ident*' press Enter
2w .......................... jump 2 words until number one  (before dot)
Ctrl-a ...................... increases the number
2w .......................... jump to number after dot
1500 Ctrl-a ................. perform increases 1500 times
q ........................... stop record to macro 'a'

if you have 300 lines with this pattern just now making

300@a
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top