Making a plugin or coding this in vimscript seems a little heavy. I believe in a plugin-free vim, and good composition with external tools.
Here is a 1-time command, based on user2571881's, that works even if the buffer has not been saved.
:%!awk -F '|' '{print; sum+=$4}; END {print "Total: "sum}'
If you want to save this command for future use, you might want to name it:
:command! -range=% -nargs=1 SumColumn <line1>,<line2>!awk -F '|' '{print; sum+=$('<args>' + 1)} END {print "Total: "sum}'
It works with visual selection. If you select a few rows and go into command mode, vim will prefix your command with :'<,'>
, which is the line range for the visual selection. So you can run:
:'<,'>SumColumn 3
and it will only sum the 3rd column of the selected rows. By default the range is %
, so
:SumColumn 3
will sum the 3rd column of all lines.
EDIT: If you want to be able to specify other field separators and default the column counted to the last one, you can cover the command in bash
and handle the arguments with it, like this:
:command! -range=% -nargs=* SumColumn <line1>,<line2>!bash -c 'awk -F ${2:-|} "{print; sum+=\$(${1:-NF - 2} + 1)} END {print \"Total: \"sum}"' sumcolumn <args>
Now,
:SumColumn
will count the last column of a table with "|" field separators,
:SumColumn 3
will count the 3rd column of a table with "|" field separators, and
:SumColumn 3 +
will count the 3rd column of a table with "+" field separators.