我正在寻找一个命令,该命令将接受(作为输入)多行文本,每行包含一个整数,并输出这些整数的总和。

作为背景知识,我有一个包含时序测量的日志文件。 通过grepping相关行和sed重新格式化,我可以列出该文件中的所有时间。 我想算出总数。 我可以将此中间输出通过管道传递给任何命令以进行最终求和。 我过去一直使用expr ,但是除非它在RPN模式下运行,否则我认为它无法应付(即使那样也很棘手)。

如何获得整数的总和?


#1楼

纯粹的打击和单线:-)

$ cat numbers.txt
1
2
3
4
5
6
7
8
9
10$ I=0; for N in $(cat numbers.txt); do I=$(($I + $N)); done; echo $I
55

#2楼

球拍内衬:

racket -e '(define (g) (define i (read)) (if (eof-object? i) empty (cons i (g)))) (foldr + 0 (g))' < numlist.txt

#3楼

纯净的和短的打击。

f=$(cat numbers.txt)
echo $(( ${f//$'\n'/+} ))

#4楼

C(未简化)

seq 1 10 | tcc -run <(cat << EOF
#include <stdio.h>
int main(int argc, char** argv) {int sum = 0;int i = 0;while(scanf("%d", &i) == 1) {sum = sum + i;}printf("%d\n", sum);return 0;
}
EOF)

#5楼

我意识到这是一个老问题,但是我很喜欢这个解决方案以分享它。

% cat > numbers.txt
1
2
3
4
5
^D
% cat numbers.txt | perl -lpe '$c+=$_}{$_=$c'
15

如果有兴趣,我将解释其运作方式。


#6楼

$ cat n
2
4
2
7
8
9
$ perl -MList::Util -le 'print List::Util::sum(<>)' < n
32

或者,您可以在命令行中输入数字:

$ perl -MList::Util -le 'print List::Util::sum(<>)'
1
3
5
^D
9

但是,此文件会使文件变得很粗糙,因此在大文件上使用它不是一个好主意。 请参阅j_random_hacker的答案 ,该答案可以避免咽 。


#7楼

我的十五美分:

$ cat file.txt | xargs  | sed -e 's/\ /+/g' | bc

例:

$ cat text
1
2
3
3
4
5
6
78
9
0
1
2
3
4
576
7
4444
$ cat text | xargs  | sed -e 's/\ /+/g' | bc
5148

#8楼

实时求和可让您监视某些数字运算任务的进度。

$ cat numbers.txt
1
2
3
4
5
6
7
8
9
10$ cat numbers.txt | while read new; do total=$(($total + $new)); echo $total; done
1
3
6
10
15
21
28
36
45
55

(在这种情况下,无需将$total设置为零。完成后,您都无法访问$ total。)


#9楼

我的版本:

seq -5 10 | xargs printf "- - %s" | xargs  | bc

#10楼

我会对公认的解决方案大加警告:

awk '{s+=$1} END {print s}' mydatafile # DO NOT USE THIS!!

这是因为awk以这种形式使用32位带符号整数表示形式:如果总和超过2147483647(即2 ^ 31),它将溢出。

一个更通用的答案(用于求和整数)将是:

awk '{s+=$1} END {printf "%.0f\n", s}' mydatafile # USE THIS INSTEAD

#11楼

与jq :

seq 10 | jq -s 'add' # 'add' is equivalent to 'reduce .[] as $item (0; . + $item)'

#12楼

替代的纯Perl,相当易读,不需要软件包或选项:

perl -e "map {$x += $_} <> and print $x" < infile.txt

#13楼

您可以使用首选的“ expr”命令,只需先稍微调整一下输入即可:

seq 10 | tr '[\n]' '+' | sed -e 's/+/ + /g' -e's/ + $/\n/' | xargs expr

该过程是:

  • “ tr”将eoln字符替换为+符号,
  • sed在两边用空格填充'+',然后从行中去除最后的+
  • xargs将管道输入插入命令行以供expr使用。

#14楼

对于红宝石爱好者

ruby -e "puts ARGF.map(&:to_i).inject(&:+)" numbers.txt

#15楼

perl -lne '$x += $_; END { print $x; }' < infile.txt

#16楼

应该做一点awk吗?

awk '{s+=$1} END {print s}' mydatafile

注意:如果要添加超过2 ^ 31(2147483647)的任何内容,某些版本的awk会有一些奇怪的行为。 有关更多背景,请参见评论。 一种建议是使用printf而不是print

awk '{s+=$1} END {printf "%.0f", s}' mydatafile

#17楼

如果您愿意的话,可以用python来做:

未经测试,只需输入:

out = open("filename").read();
lines = out.split('\n')
ints = map(int, lines)
s = sum(ints)
print s

塞巴斯蒂安指出了一个衬里脚本:

cat filename | python -c"from fileinput import input; print sum(map(int, input()))"

#18楼

以下是bash的工作原理:

I=0for N in `cat numbers.txt`
doI=`expr $I + $N`
doneecho $I

#19楼

Python的一线版:

$ python -c "import sys; print(sum(int(l) for l in sys.stdin))"

#20楼

BASH解决方案,如果要将此命令用作命令(例如,如果需要经常执行此操作):

addnums () {local total=0while read val; do(( total += val ))doneecho $total
}

然后用法:

addnums < /tmp/nums

#21楼

普通打击:

$ cat numbers.txt
1
2
3
4
5
6
7
8
9
10
$ sum=0; while read num; do ((sum += num)); done < numbers.txt; echo $sum
55

#22楼

以下应能工作(假设您的电话号码是每行的第二个字段)。

awk 'BEGIN {sum=0} \{sum=sum + $2} \
END {print "tot:", sum}' Yourinputfile.txt

#23楼

您可以使用num-utils,尽管对于您所需的功能而言可能有些过分。 这是一组用于在Shell中处理数字的程序,可以做一些漂亮的事情,当然包括加起来。 有点过时了,但是它们仍然可以工作,如果您需要做更多的事情,可能会很有用。

http://suso.suso.org/programs/num-utils/


#24楼

我认为AWK是您想要的:

awk '{sum+=$1}END{print sum}'

您可以通过将数字列表传递到标准输入或通过将包含数字作为参数的文件传递来使用此命令。


#25楼

粘贴通常会合并多个文件的行,但也可用于将文件的各个行转换为单个行。 分隔符标志允许您将x + x类型方程式传递给bc。

paste -s -d+ infile | bc

或者,当从标准输入进行配管时,

<commands> | paste -s -d+ - | bc

#26楼

dc -f infile -e '[+z1<r]srz1<rp'

请注意,带负号前缀的负数应转换为dc ,因为它使用_前缀而不是-前缀。 例如,通过tr '-' '_' | dc -f- -e '...' tr '-' '_' | dc -f- -e '...'

编辑:由于此答案获得了很多票“默默无闻”,这里是详细的解释:

表达式[+z1<r]srz1<rp 执行以下操作 :

[   interpret everything to the next ] as a string+   push two values off the stack, add them and push the resultz   push the current stack depth1   push one<r  pop two values and execute register r if the original top-of-stack (1)is smaller
]   end of the string, will push the whole thing to the stack
sr  pop a value (the string above) and store it in register r
z   push the current stack depth again
1   push 1
<r  pop two values and execute register r if the original top-of-stack (1)is smaller
p   print the current top-of-stack

作为伪代码:

  1. 将“ add_top_of_stack”定义为:

    1. 从堆栈中删除两个顶部值,然后将结果加回去
    2. 如果堆栈具有两个或多个值,请递归运行“ add_top_of_stack”
  2. 如果堆栈具有两个或多个值,请运行“ add_top_of_stack”
  3. 打印结果,现在是堆栈中剩下的唯一项目

为了真正理解dc的简单性和功能,下面是一个有效的Python脚本,该脚本实现了dc某些命令并执行了上述命令的Python版本:

### Implement some commands from dc
registers = {'r': None}
stack = []
def add():stack.append(stack.pop() + stack.pop())
def z():stack.append(len(stack))
def less(reg):if stack.pop() < stack.pop():registers[reg]()
def store(reg):registers[reg] = stack.pop()
def p():print stack[-1]### Python version of the dc command above# The equivalent to -f: read a file and push every line to the stack
import fileinput
for line in fileinput.input():stack.append(int(line.strip()))def cmd():add()z()stack.append(1)less('r')stack.append(cmd)
store('r')
z()
stack.append(1)
less('r')
p()

#27楼

sed 's/^/.+/' infile | bc | tail -1

#28楼

不能避免提交以下内容:

jot 1000000 | sed '2,$s/$/+/;$s/$/p/' | dc

在这里找到:
最优雅的unix shell单线求和列表的任意精度是多少?

与awk,bc和朋友相比,这是它的特殊优势:

  • 它不依赖于缓冲,因此不会因很大的输入而阻塞
  • 它表示没有特定的精度-或该问题的整数大小-限制
  • 如果需要添加浮点数,则无需其他代码

#29楼

我对现有答案做了一个快速基准测试

  • 仅使用标准工具(对不起luarocket类的东西),
  • 是真正的一线客
  • 有能力增加大量的数字(1亿),并且
  • 速度很快(我忽略了花费一分钟以上的时间)。

我总是将1到1亿的数字相加,这在我的计算机上可以在不到一分钟的时间内完成几种解决方案。

结果如下:

蟒蛇

:; seq 100000000 | python -c 'import sys; print sum(map(int, sys.stdin))'
5000000050000000
# 30s
:; seq 100000000 | python -c 'import sys; print sum(int(s) for s in sys.stdin)'
5000000050000000
# 38s
:; seq 100000000 | python3 -c 'import sys; print(sum(int(s) for s in sys.stdin))'
5000000050000000
# 27s
:; seq 100000000 | python3 -c 'import sys; print(sum(map(int, sys.stdin)))'
5000000050000000
# 22s
:; seq 100000000 | pypy -c 'import sys; print(sum(map(int, sys.stdin)))'
5000000050000000
# 11s
:; seq 100000000 | pypy -c 'import sys; print(sum(int(s) for s in sys.stdin))'
5000000050000000
# 11s

Awk

:; seq 100000000 | awk '{s+=$1} END {print s}'
5000000050000000
# 22s

粘贴和密件抄送

这用完了我机器上的内存。 它的工作量仅为输入量(5,000万个数字)的一半:

:; seq 50000000 | paste -s -d+ - | bc
1250000025000000
# 17s
:; seq 50000001 100000000 | paste -s -d+ - | bc
3750000025000000
# 18s

因此,我想一亿个数字大约需要35秒钟。

佩尔

:; seq 100000000 | perl -lne '$x += $_; END { print $x; }'
5000000050000000
# 15s
:; seq 100000000 | perl -e 'map {$x += $_} <> and print $x'
5000000050000000
# 48s

红宝石

:; seq 100000000 | ruby -e "puts ARGF.map(&:to_i).inject(&:+)"
5000000050000000
# 30s

C

为了比较起见,我编译了C版本并对其进行了测试,以了解基于工具的解决方案的速度。

#include <stdio.h>
int main(int argc, char** argv) {long sum = 0;long i = 0;while(scanf("%ld", &i) == 1) {sum = sum + i;}printf("%ld\n", sum);return 0;
}
:; seq 100000000 | ./a.out
5000000050000000
# 8s

结论

C当然是8s最快的,但是Pypy解决方案只增加了很少的开销,大约是11s的30% 。 但是,公平地说,Pypy并非完全标准。 大多数人只安装了CPython,速度明显慢(22秒),与流行的Awk解决方案一样快。

基于标准工具的最快解决方案是Perl(15s)。


#30楼

普通打击一线

$ cat > /tmp/test
1
2
3
4
5
^D$ echo $(( $(cat /tmp/test | tr "\n" "+" ) 0 ))

Shell命令对整数求和,每行一个?相关推荐

  1. UEFI Shell命令详解,自写一个UEFI Shell命令

    首先,我们从BIOS进入Shell,输入help命令查看帮助信息 Shell:helpacpiview - Display ACPI Table information. alias - Displa ...

  2. 单片机shell命令_单片机裸机下写一个自己的shell调试器

    result = paramBuffer[i] -'A'+10; } else { //出现范围之外的数据,返回1 return 1; } valueResult += (u32)(result*fa ...

  3. java 远程shell脚本_java通过ssh连接服务器执行shell命令详解及实例

    java通过ssh连接服务器执行shell命令详解 java通过ssh连接服务器执行shell命令:JSch 是SSH2的一个纯Java实现.它允许你连接到一个sshd 服务器,使用端口转发,X11转 ...

  4. mysql执行shell命令_关键Docker命令:使用Docker必须掌握的公认宝典

    读者可以将下面的命令纲要当作成功使用Docker必须掌握的公认宝典--从搜索和构建镜像到创建自己的Dockerfile.我们先看一些简单的命令,然后在此基础上接触更复杂的命令. 7.1.1 docke ...

  5. java执行shell命令权限不够_Java调用shell脚本解决传参和权限问题的方法|chu

    1. java 执行shell java 通过 Runtime.getRuntime().exec() 方法执行 shell 的命令或 脚本,exec()方法的参数可以是脚本的路径也可以是直接的 sh ...

  6. chatgpt赋能python:PythonSh-一个强大的Shell命令助手

    Python Sh - 一个强大的Shell命令助手 Python Sh 是一个基于 Python 的 CLI 工具,它可以让 Python 开发人员更加便利地使用 Shell 命令.Python S ...

  7. Java黑皮书课后题第7章:*7.21(整数求和)编写程序,从命令行输入不定数目的整数,然后显示它们的和

    *7.21(整数求和)编写程序,从命令行输入不定数目的整数,然后显示它们的和 题目 题目描述 破题 代码 运行实例 题目 题目描述 7.21(整数求和)编写程序,从命令行输入不定数目的整数,然后显示它 ...

  8. linux里返回状态命令行,Shell $?获取函数返回值或者上一个命令的退出状态

    $? 是一个特殊变量,用来获取上一个命令的退出状态,或者上一个函数的返回值. 所谓退出状态,就是上一个命令执行后的返回结果.退出状态是一个数字,一般情况下,大部分命令执行成功会返回 0,失败返回 1, ...

  9. Shell命令行操作

    1.1 shell提示符 [me@linuxbox ~]$ 如果最后一个字符是"#",表示当前终端会话有超级用户权限.使用root用户登录或者使用能提供超级用户权限的终端能获得该权 ...

最新文章

  1. java自适应table_【进阶之路】包罗万象——JAVA中的锁
  2. python的多线程threading_Python中多线程thread与threading的实现方法,pythonthreading
  3. [vb] Set 语句
  4. 上架服务器必须做的准备工作
  5. Jmeter(二十三)稳定性测试后的波形图
  6. uniapp 微信小程序生成二维码
  7. 最少拍控制系统设计(一)-- 最少拍无纹波系统的设计方法
  8. oracle写一个全量刷新,Oracle物化视图定时全量刷新导致归档日志骤增
  9. Excel自动求和-乘法
  10. Hibernate框架的入门级学习运用
  11. Walle和加固宝的优雅结合
  12. 城镇污水处理厂工艺概述及提标改造路线
  13. JavaScript 排他思想
  14. split(),slice(),splice()的区别与应用
  15. 计算机应用说课稿,中职计算机说课稿
  16. MySQL的主从配置+SpringBoot的MySQL读写分离配置
  17. [Matlab]巴特沃夫滤波器设计:低通、高通、带通和带阻
  18. 小议阿里云数加平台对企业有何帮助?
  19. 嵌入式系统设计(一)
  20. 地理空间技术改变世界的未来

热门文章

  1. CSS3 :nth-child()伪类选择器
  2. java解析json的一种方法
  3. abstract、virtual、override 和 new
  4. 中国开放教育资源协会
  5. Django相关配置(包括数据库、templates、static等)信息—Django2.0
  6. 【Mac + Appium + Python3.6学习(四)】之常用的IOS自动化测试API总结
  7. 【洛谷1962】 斐波那契数列
  8. 配置多个git账号或多个SSH账号
  9. keepalived安装及配置文件详解
  10. nginx一招配置,帮你快速隐藏php后缀名