我正在寻找一个命令,它将接受多行文本作为输入,每行包含一个整数,并输出这些整数的总和 .
作为一个背景,我有一个日志文件,其中包括时序测量,所以通过grepping相关的行,以及一些 sed
重新格式化我可以列出该文件中的所有时间 . 我'd like to work out the total however, and my mind has gone blank as to any command I can pipe this intermediate output to in order to do the final sum. I'过去总是使用 expr
,但除非它在 RPN mode
中运行,否则我不会应对这个问题(即便如此,它也会很棘手) .
我错过了什么?鉴于可能有多种方法可以实现这一点,我将很乐意阅读(和 upvote
)任何有效的方法,即使其他人已经发布了一个不同的解决方案来完成这项工作 .
相关问题:Shortest command to calculate the sum of a column of output on Unix?(credits @Andrew)
Update :哇,正如所料,这里有一些不错的答案 . 看起来我一定要把 awk
更深入的检查作为 command-line tool
一般!
30 回答
使用jq:
我十五美分:
例:
Racket中的单线程:
普通bash一个衬垫
我认为AWK正是您所寻找的:
您可以通过将数字列表传递给标准输入或将包含数字的文件作为参数传递来使用此命令 .
Python中的单行版本:
你可以在python中做到这一点,如果你觉得舒服:
未经测试,只需输入:
塞巴斯蒂安指出了一个单行脚本:
我意识到这是一个老问题,但我喜欢这个解决方案足以分享它 .
如果有兴趣,我会解释它是如何工作的 .
实时汇总,让您监控一些数字运算任务的进度 .
(在这种情况下,无需将
$total
设置为零 . 完成后,您也无法访问$ total . )纯粹和短暂的bash .
替代纯Perl,相当可读,不需要包或选项:
以下应该有效(假设您的号码是每行的第二个字段) .
以下在bash中有效:
我的版本:
或者,您可以在命令行上键入数字:
但是,这个文件会使文件丢失,所以在大文件上使用它不是一个好主意 . 见j_random_hacker's answer,这可以避免啜饮 .
纯粹的bash和单线:-)
C(未简化)
您可以使用首选的'expr'命令,您只需先输入一点输入:
过程是:
"tr"用符号替换eoln字符,
sed填充'+',每侧有空格,然后从线上剥去最后一个
xargs将管道输入插入到命令行中以供expr使用 .
C(简化):
SCC项目 - http://volnitsky.com/project/scc/
SCC是shell提示符下的C片段评估程序
对于Ruby Lovers
你可以使用num-utils,虽然它可能对你需要的东西有点过分 . 这是一组用于操作shell中的数字的程序,可以做几个漂亮的事情,当然包括添加它们 . 它有点过时了,但是如果你需要做更多的事情,它们仍然可以工作并且非常有用 .
http://suso.suso.org/programs/num-utils/
BASH解决方案,如果你想让它成为一个命令(例如,如果你需要经常这样做):
然后用法:
粘贴通常合并多个文件的行,但它也可用于将文件的各行转换为单行 . 分隔符标志允许您将x x类型方程传递给bc .
或者,当从stdin管道时,
有点awk应该这样做吗?
注意:如果您要添加超过2 ^ 31(2147483647)的任何内容,某些版本的awk会有一些奇怪的行为 . 有关更多背景,请参阅评论一个建议是使用
printf
而不是print
:我会对通常认可的解决方案提出一个很大的警告:
这是因为在这种形式下,awk使用32位有符号整数表示:对于超过2147483647(即2 ^ 31)的和,它将溢出 .
更一般的答案(对于求和整数)将是:
附:我本来想评论第一个答案,但我没有足够的声誉..
我已经对现有答案做了快速基准测试
只使用标准工具(抱歉
lua
或rocket
之类的东西),是真正的单行,
能够增加大量的数字(1亿),和
很快(我忽略了花了一分钟以上的那些) .
我总是添加1到1亿的数字,这在我的机器上可行的不到一个几分钟的解决方案 .
结果如下:
Python
Awk
粘贴&Bc
这在我的机器上耗尽了内存 . 它的工作量只有输入的一半(5000万个数字):
所以我想这对于1亿个数字来说需要大约35秒 .
Perl
Ruby
C.
仅仅为了比较,我编译了C版本并对其进行了测试,只是想知道基于工具的解决方案有多慢 .
结论
C当然是最快的8s,但 the Pypy solution only adds a very little overhead of about 30% to 11s . 但是,公平地说,Pypy并不完全是标准的 . 大多数人只安装了CPython,速度明显慢了(22s),与流行的Awk解决方案一样快 .
The fastest solution based on standard tools is Perl (15s).
普通狂欢:
请注意,前缀为减号的负数应翻译为
dc
,因为它使用_
前缀而不是-
前缀 . 例如,通过tr '-' '_' | dc -f- -e '...'
.编辑:由于这个答案得到了很多“默默无闻”的投票,这里有一个详细的解释:
表达式
[+z1<r]srz1<rp
does the following:作为伪代码:
将"add_top_of_stack"定义为:
从堆栈中删除两个顶部值并将结果添加回来
如果堆栈有两个或更多值,则递归运行"add_top_of_stack"
如果堆栈有两个或更多值,请运行"add_top_of_stack"
打印结果,现在是堆栈中剩余的唯一项目
要真正理解
dc
的简单性和强大功能,这里有一个有效的Python脚本,它实现了dc
中的一些命令,并执行上述命令的Python版本: