| 13/05/15 | 09:30-16:00 | 6.5 |
| 14/05/15 | 10:00-16:30 | 6.5 |
| 16/05/15 | 15:30-01:00 | 9.5 |
| 21/05/15 | 09:00-16:30 | 7.5 |
| 22/05/15 | 08:30-17:00 | 8.5 |
| 28/05/15 | 09:30-15:30 | 6 |
| 02/06/15 | 09:00-20:00 | 11 |
| 03/06/15 | 08:30-22:30 | 14 |
我正在寻找一种方法来快速计算第三列的总和并将其插入缓冲区。我想到的解决方案将使用可视块模式(选择所有数字)以及表达式寄存器(进行数学计算)。
使用本机Vim命令是否可能?如果没有,是否有可以帮助我的插件?
#1 楼
我写了一个插件:https://github.com/sk1418/HowMuch,它支持可视选择并进行数学计算。默认情况下,该插件支持三个数学表达式评估引擎:Gnu bc,python,和vimscript。您可以对某一项进行计算,也可以让插件自动为您选择一种。
它适用于您的示例,如下所示:
有关详细信息,请阅读github上的自述文件。
评论
如果您包括选择,求和和插入答案所需的击键,将很有帮助。
– pdoherty926
17年4月4日在16:32
@ pdoherty926有关详细信息,请阅读github上的自述文件。即使我在此处输入了要解决此问题的按键,也看不出它有多大用处,只是3或4个按键组合。如果某人确实需要我的脚本,他/她将始终检查详细信息。
–肯特
17年12月4日在16:46
#2 楼
如果您不想使用插件或拖放到bash脚本,则可以执行以下操作:c-V {motions} "ay
将列复制到"a
:let @a = substitute(@a, 'c-V c-J', '+', 'g')
用+
替换列换行符ic-R=c-Ra
通过表达式寄存器运行替换的"a
或者:使表达式历史记录条目可重复用于列的更多总和
ctrl-V {motions} y
将列放入拉动寄存器""
ictrl-R=eval(substitute(@", '\n', '+', 'g'))
重复另一列:
ctrl-V {motion} y
(不变)ictrl-R=<CR>
,或者如果您对表达式寄存器做了其他操作,请向上滚动历史记录箭头键(如果重新映射,则带有ctrl-P
):ictrl-R=<up>...<up><CR>
评论
由于某种原因,我只设法在您的替代命令上使用双引号“而不是单引号”。
–vappolinario
2015年9月10日19:52
@vappolinario对我来说都是双向的,所以我很抱歉,我不知道。
– Hovercouch
2015年9月10日20:17在
@Hovercouch您能否详细说明第三步?确切地说,如何通过表达式寄存器运行替换?
– pdoherty926
17年4月4日在16:09
如何制作地图:`nnoremap
– SergioAraujo
19年7月3日在17:35
#3 楼
:r!awk '{sum+=} END {print "Total: "sum}' %
说明:
:r ........... read (put result in this file)
! ............ external command
awk .......... external tool
{sum+=} .... sixth field (awk considers spaces as field separator)
END .......... at the end
{print "Total: "sum} --> string "Total: " plus your result
% ............ current file
我一直在尝试在这里工作的函数:
" This function requires you select the numbers
fun! SumVis()
try
let l:a_save = @a
norm! gv"ay
let @a = substitute(@a,'[^0-9. ]','+','g')
exec "norm! '>o"
exec "norm! iTotal \<c-r>=\<c-r>a\<cr>"
finally
let @a = l:a_save
endtry
endfun
vnoremap <leader>s :<C-u>call SumVis()<cr>
使用上面包含的地图,在加载该函数之后,您要做的就是选择要求和的数字,然后使用
<leader>s
对选定区域求和。功能说明:
它使用
try/finally/endtry
拉伸来捕获错误。 let l:a_save = @a .......... if whe have register 'a' we save it temporarelly
norm! gv"a ................................... gv --> reselects and captures selection to 'register a'
let @a = substitute(@a,'[^0-9. ]','+','g') .... removes all but numbers, dots and spaces from 'register a' and puts '+' among the numbers
exec "norm! '>o" ............................. opens new line bellow selection. see :h '>
exec "norm! iTotal: \<c-r>=\<c-r>a\<cr>" ...... insert "Total: " plus 'expression register result
let @a = l:a_save ............................. restores original 'a' register content
如果要尝试使用此功能,请执行以下操作:
在浏览器中复制此功能并在vim上运行此命令
:@+
这将使您可以正常使用
:call SumVis()
。 :@+ ......... loads `+` register making the function avaiable
它需要您使用ctrl + v进行可视块选择,取消选择并最终调用该函数。或者,您可以使用建议的地图,它本身会在计算之前删除选择。
#4 楼
我的csv插件允许这样做。使用:SumCol
命令,并确保已阅读文档。#5 楼
制作插件或在vimscript中编码似乎有点沉重。我相信无插件的vim以及使用外部工具的良好组合。这是一个基于user2571881的1次命令,即使未保存缓冲区也可以使用。
:%!awk -F '|' '{print; sum+=}; END {print "Total: "sum}'
如果要保存此命令以备将来使用,则可能要命名为:
:command! -range=% -nargs=1 SumColumn <line1>,<line2>!awk -F '|' '{print; sum+=$('<args>' + 1)} END {print "Total: "sum}'
它与视觉选择一起使用。如果选择几行并进入命令模式,vim将在命令前面加上
:'<,'>
,这是可视选择的行范围。因此,您可以运行::'<,'>SumColumn 3
,它将仅对所选行的第三列求和。默认情况下,范围是
%
,因此:SumColumn 3
将加总所有行的第三列。
编辑:如果您希望若要指定其他字段分隔符并将列默认为最后一个列,则可以覆盖
bash
中的命令并使用它来处理参数,如下所示::command! -range=% -nargs=* SumColumn <line1>,<line2>!bash -c 'awk -F ${2:-|} "{print; sum+=$(${1:-NF - 2} + 1)} END {print \"Total: \"sum}"' sumcolumn <args>
现在,
:SumColumn
将用“ |”计数表的最后一列字段分隔符,
:SumColumn 3
将用“ |”计数表的第三列字段分隔符,并且
:SumColumn 3 +
将计算带有“ +”字段分隔符的表的第三列。
评论
一个人如何处理其他可能的字段分隔符?只是为了使解决方案更通用。
–塞尔吉奥·阿劳霍(Sergio Araujo)
17年9月15日在15:59
@ user2571881,我已经编辑了答案,显示了这一点。
– JoL
17年9月15日在16:32
@JoL在VIMRC中添加SumColumn之类的功能意味着您只需在VIMRC中安装“插件”即可。希望您擅长于随时间进行维护。对我来说,插件提供了文档,可以利用其他独创性分成有意义的部分。我为上游开发做出了贡献,它改进了令人惊叹的插件,没有人有时间自己创建所有插件(tpope除外)。您是否不使用vim-surround,vim-fugitive,vim-easy-align / vim-lion,vim-unmpaired,vim-commentary,ultisnips或ft特定的工具(例如vim-go,vim-rails,vimtex)?
–霍奇克
18年7月26日在10:54
@Hotschke当我到达这里时,我看到了一个问题,并想:“好吧,只是通过awk。”但是然后,我看到了公认的答案是:“嘿,下载并安装数百个LOC插件。”第三个答案是,“嘿,下载并安装此数千个LOC插件。”这是过度杀伤和膨胀。即使您一生中需要多次对列求和,这也是过分的。我的答案旨在说明如何仅需执行一次就可以在单个无插件,无废话命令中执行此操作,以及如何在需要执行此操作的情况下使用带有参数的简单命令经常。
– JoL
18年7月26日在15:31
@Hotschke为了回答您的问题,我曾经将每个插件安装在看起来很凉爽的阳光下,但是后来我的vim变得异常缓慢(读“一点点懒”对于编辑器是无法忍受的)。在深入研究vim文档时,我意识到我并不需要插件。许多常用功能已经足够好,对于vim所没有的功能,shell是必经之路。根据Unix哲学,从根本上讲(忽略它造成的异常),vim是一个与其他OS工具良好地互操作的编辑器。我相信这是最好地利用它的方式。此后没有插件。
– JoL
18年7月26日在15:32
#6 楼
如果列已正确对齐,则可以使用简单的oneliner来完成。首先以逐块可视化模式选择列,因为其他答案已经证明了->
CTRL-V
+移动光标用
y
取消选择类型:
:echo eval(join(split(@", '\_s\+'), '+'))
,它将在空格和换行符上拉的文本分开,用+
字符重新加入元素,然后评估字符串。另一种方法继续:用
+
替换换行符并求值::echo eval(substitute(@", "\n", '+', 'g'))
-eval()
是我们与reduce
最接近的东西。如果没有,则必须使用其他技巧来计数字段。例如,
split(getline('.'), "[ \t|]\+")
可用于从阵列中的行拆分列。从那里开始,它变得非常简单:以可视模式选择行
:echo eval(join(map(getline("'<", "'>"), { -> split(v:val, "[ \t|]\+")[2] }), '+'))
为了摆脱神奇的价值(字段号-1和
+
),它可以成为命令:command! -range=% -nargs=+ OnField
\ echo { field, what -> eval(join(map(getline(<line1>, <line2>), { -> split(v:val, "[ \t|]\+")[field-1] }), what))}(<f-args>)
可与以下命令一起使用:
:OnField 3 +
:2,5OnField 3 +
:'<,'>Onfield 3 * " after line-wise selection
....
注意:这里我使用的是Vim 7.4.1xxx中的lambdas。
评论
从8.2.0878开始,Vim提供了reduce()函数。因此,您也可以这样写:echo split(@“,'\ _s \ +')-> map(” str2float(v:val)“)-> reduce({a,v-> a + v})。
–user938271
20年6月23日22:30在
#7 楼
Damian Conway的插件++
中的vmap vmath
从github安装插件(仅178 sloc)
例如
$ wget https://raw.githubusercontent.com/thoughtstream/Damian-Conway-s-Vim-Setup/master/plugin/vmath.vim -P ~/.vim/pack/manual/start/damians-tools/plugin
将映射添加到您的vimrc
vmap <silent><expr> ++ VMATH_YankAndAnalyse()
但是,我建议使用其他东西,例如
gA
移至第三列
2f|
并以可视块模式选择列<C-V>G$
按
++
(或您选择的映射)结果显示并存储在寄存器中(
s
中的总和)从寄存器
s
中插入和,例如带有"sp
有关此插件的演示,请参见YouTube视频Damian Conway,“更多即时更好的Vim”-OSCON 2013(从第29分钟开始)。
#8 楼
来自csvkit的外部cli工具csvstat
:!csvstat -d '|' -H -c 4 --sum %
69.5
选项的简短说明
-d DELIMITER
定界输入CSV文件的字符。在这里|
。-H
指定输入的CSV文件没有标题行。-c COLUMNS
检查以逗号分隔的列索引或名称列表。默认为所有列。--sum
仅输出总和。此工具还提供最小值,最大值,平均值,中位数,stdev(标准偏差),计数唯一值,列表频繁的值。
使用
<C-r>=system("csvstat -d '|' -H -c 4 --sum FILENAME 2> /dev/null")
插入文件
安装
在macOS上,可以通过自制程序及以下版本使用csvkit Debian / Ubuntu及其类似版本可以与
$ sudo apt install csvkit
一起安装。
评论
您可以看一下这篇文章:vim.wikia.com/wiki/Using_vim_as_calculator