**Tip 205**Printable Monobook Previous Next

**created** 2002 · **complexity** intermediate · **author** Stanislav Sitar · **version** 6.0

Here is how to calculate the sum of all numbers matching some pattern, for example, the first number on each line with a number, or the numbers following a `$`

($10+$20). This version only handles unsigned integers.

## Sum function[edit | edit source]

First, define the following function.

let g:S = 0 "result in global variable S function! Sum(number) let g:S = g:S + a:number return a:number endfunction

In Vim, you could copy the above lines then type `:@"`

to execute the copied lines (to define the function). Or, you could put the code in a file in your plugin directory, or in your vimrc.

The function adds the given number onto the sum in the global variable `S`

. The function returns the given number so that it can be used in a substitute command without changing the number.

## Usage[edit | edit source]

Suppose you have this text:

Here are some items: Take 10 apples and 20 pears then 30 walnuts.

You can add the numbers with these commands:

:let g:S=0 :%s/\d\+/\=Sum(submatch(0))/ :echo g:S

The first line clears the variable used to hold the sum. The third line displays the sum.

The substitute replaces the first occurrence of `\d\+`

(one or more digits) on each line. The replacement `\=`

is the result of the expression `Sum(submatch(0))`

which calls the `Sum()`

function. The `submatch(0)`

is the text matched by the search pattern (the number which was found).

Using the following would include all numbers in each line:

:%s/\d\+/\=Sum(submatch(0))/g

This adds only the numbers following a `$`

character (the `\zs`

starts the search hit after the `$`

is found):

:%s/\$\zs\d\+/\=Sum(submatch(0))/g

This adds only the last number on each line that contains a number:

:%s/.*\zs\d\+/\=Sum(submatch(0))/

## References[edit | edit source]

## Comments[edit | edit source]

If you want to replace the numbers in the file with a running total, in the `Sum()`

function, replace:

return a:number

with

return g:S

### Floats[edit | edit source]

Float numbers could be handled easily:

:%s/\d\+/\=Sum(str2float(submatch(0)))/g

- The above does not work because the search pattern only finds unsigned integers. Also I do not think str2float is needed. This might be fixed and moved back into the tip. JohnBeckett (talk) 06:13, September 9, 2014 (UTC)
- It does work for me as follows :
- In .vimrc I have :
let g:S = 0 function! Sum(number) let g:S = g:S + str2float(a:number) return a:number endfunction

- Usage :
:let g:S=0 :%s/[0-9\.]\+/\=Sum(submatch(0))/ :echo g:S