Reputation: 375
I have some parameters in a text file which goes as follows
parameter1 =5
parameter2=4
----------
---------
parameter(n-1) = 6
parameter(n)=11
My requirement is that the values of the parameters should sum upto 100 and there can be number of parameters. I was wondering if I could write a function in Vim , which could calculate the sum and display it somewhere? I have no idea how to pass arguement to such a function,I was thinking it could somehow be done by block selecting the lines with parameter values.
Upvotes: 1
Views: 955
Reputation: 32966
This can also be done with a (pseudo) one-liner as well:
:let s=0
:g/parameter\d\+\s*=\s*\d\+/let s+=matchstr(getline('.'), '\d\+\s*$')
:echo s
It you want a function you fall back to Birei's solution
EDIT: BTW, we can also echo it directly with:
echo eval(join(map(filter(getline(1,'$'), 'v:val =~ "=\\s*\\d"'), 'matchstr(v:val, "=\\s*\\zs\\d\\+")'), '+'))
or if you prefer a command:
command! -nargs=0 -range=% Sum echo eval(join(map(filter(getline(<line1>,<line2>), 'v:val =~ "=\\s*\\d"'), 'matchstr(v:val, "=\\s*\\zs\\d\\+")'), '+'))
Upvotes: 0
Reputation: 36282
Add following function to your vimrc
file:
function! CustomSum()
let sum = 0
for l in range( 1, line('$') )
let fields = split( getline(l), '\s*=\s*' )
if ( len( fields ) != 2 || fields[1] =~? '\D' )
continue
endif
let sum = sum + fields[1]
endfor
return sum
endfunction
And run it:
:echo CustomSum()
That with your input data yields:
26
EDIT to add a range to previous function. Now accepts a range as input parameters named a:firstline
and a:lastline
. I increment them with 0
to convert them to integers, otherwise the range
function complains. Last line echoes the result for debugging but would be better idea to handle the result in a return call (only uncomment it).
function! CustomSum() range
let sum = 0
for l in range( a:firstline + 0, a:lastline + 0 )
let fields = split( getline(l), '\s*=\s*' )
if ( len( fields ) != 2 || fields[1] =~? '\D' )
continue
endif
let sum = sum + fields[1]
endfor
echo sum
"" return sum
endfunction
Now you can do visually selection or normal ranges, like:
:'<,'>call CustomSum()
or
:1,5call CustomSum()
Both should work.
Upvotes: 2