如何在Bash中添加一列数字

如何在Bash中添加一列数字

介绍

本文研究了如何在bash shell中对数据的数字列进行累加,研究了可用于该任务的bash工具并比较了它们的速度。

使用awk工具

我们先用awk(awk)程序来计算某一列的数值之和。

$ awk '{Total=Total+$1} END{print "Total is: " Total}' numbers.csv
Total is: 49471228

现在让我们用 “时间 “命令来看看计时的情况 —

$ time awk '{Total=Total+$1} END{print "Total is: " Total}' numbers.csv
Total is: 49471228
 
real 0m0.228s
user 0m0.141s
sys 0m0.047s

当文件包含多列时

我们已经看到了如何使用awk来计算文件中一行的总和。现在让我们来看看如何计算一个文件中多行的总和。

$ cat prices.csv
Books,40
Bag,70
Dress,80
Box,10

这里,文件price.csv有两列。我们现在要计算第二列中的数值之和。

$ awk -F "," '{Total=Total+$2} END{print "Total is: " Total}' prices.csv
Total is: 200

当文件包含一个标题行时

有时,文本或CSV文件的标题也包括包含列名的一行。我们将使用这些列名来帮助我们理解文件的内容。让我们编辑我们的price.csv文件,并在顶部添加一个新的行–

$ cat prices.csv
Item,Value
Books,40
Bag,70
Dress,80
Box,10

当文件包括一个标题时,我们要在文本处理发生之前删除标题。首先,让我们给我们的输入数据集添加一个额外的字段,称为 “标题”。然后,我们写一个脚本,读取文件中的每一条记录,并将新字段的值加到总数中。最后,我们将打印出结果。

$ awk -F "," 'NR!=1{Total=Total+$2} END{print "Total is: " Total}' prices.csv
Total is: 200

然后我们将看看其他一些在一列中进行加法的方法,并看看awk的方法与它们相比如何。

用Bash循环进行迭代

Awk是一个强大的工具,但我们也可以使用for循环来迭代我们列中的每个值。

使用expr命令

我们要做一个实验,看看我们是否能用expr函数来计算for循环里面的数字的总和。

$ time (sum=0;for number in `cat numbers.csv`; do sum=`expr $sum + $number`; done; echo "Total is: $sum")
Total is: 49471228
 
real 212m48.418s
user 7m19.375s
sys 145m48.203s

使用算术扩展

由于使用 “扩展 “没有什么帮助,我们将尝试另一种方法,使用算术表达式–

$ time (sum=0;for number in `cat numbers.csv`; do sum=$((sum+number)); done; echo "Total is: $sum")
Total is: 49471228
 
real 0m1.961s
user 0m1.813s
sys 0m0.125s

为了计算总数,我们将利用算术运算符。与expr运算符不同,$ (…)运算符可以处理整数和浮点数。

用bc命令添加值

bc命令对由多行组成的表达式进行计算。因此,我们必须将这些数字串联成一行,用加法运算符将它们分开。然后我们将产生的字符串传递给bc来执行计算。这里有几种方法可以做到这一点。

使用 “paste “命令

首先,我们来看看 “PASET “命令,将我们数据集的前十个数字排列在一行。

$ cat numbers.csv| head -10 | paste -sd+ -
2+44+6+15+23+0+15+88+82+1

选项-s确保粘贴时将每个条目打印在自己的行中。我们还使用了+d选项,在每个条目之间添加 “+”符号作为分隔符。

现在我们已经涵盖了基础知识,让我们继续向bc命令提供我们的输入。

$ time echo "Total is: $(cat numbers.csv | paste -sd+ - | bc)"
Total is: 49471228
 
real 0m0.244s
user 0m0.203s
sys 0m0.063s

使用 tr 命令

让我们再次使用tr(音译)函数,从一个现有的字符串中创建一个新的字符串。

$ cat numbers.csv | head -10 |tr "  
" "+"
2+44+6+15+23+0+15+88+82+1+

我们在字符串的开头多加了一个0,这样我们就可以使用bc命令来进行加法运算。然而,注意到在字符串的末尾多了一个’+’。为了解决这个问题,我们可以简单地在行末追加一个零。

$ cat numbers.csv | head -10 |tr "  
" "+" ; echo "0"
2+44+6+15+23+0+15+88+82+1+0

让我们把上一条命令的结果重定向到bc命令中。

$ time ((cat numbers.csv | tr "  
" "+" ; echo "0") | bc)
49471228
 
real 0m0.217s
user 0m0.203s
sys 0m0.031s

结合使用tr和bc命令比使用awk运行得更快。

使用sed命令

我们最后将使用sed命令来生成我们的序列。

$ cat numbers.csv | head -10 | sed -z 's#  
#+#g'
2+44+6+15+23+0+15+88+82+1+

我们已经更换了新的线路(”
“)与加号(”+”)运算符,使用sed命令的搜索和替换选项,并在结尾处打印零来处理额外的加号运算符。

$ time ((cat numbers.csv | sed -z 's#  
#+#g' ; echo "0") | bc)
49471228
 
real 0m0.343s
user 0m0.281s
sys 0m0.109s

要改变换行的含义,请使用”-z “选项。现在它们将被视为空字符,而不是将换行线解释为每个输入的开始。

如果你要处理大量的文本,你可能想用sed而不是tr。

结论

我们研究了在bash shell中对各列数字进行加法的不同方法。

我们首先讨论了awk命令的使用。然后我们讨论了处理包含多列或带有标题的单列的文件的方法。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程