如何在 Bash 中找到数组元素的总和?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13635293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 23:02:04  来源:igfitidea点击:

How can I find the sum of the elements of an array in Bash?

arraysbashshellunix

提问by BobbyT28

I am trying to add the elements of an array that is defined by user input from the read -acommand. How can I do that?

我正在尝试添加由read -a命令中的用户输入定义的数组元素。我怎样才能做到这一点?

回答by perreal

read -a array
tot=0
for i in ${array[@]}; do
  let tot+=$i
done
echo "Total: $tot"

回答by gniourf_gniourf

Given an array (of integers), here's a funny way to add its elements (in bash):

给定一个数组(整数),这是一种添加其元素的有趣方法(在 bash 中):

sum=$(IFS=+; echo "$((${array[*]}))")
echo "Sum=$sum"

e.g.,

例如,

$ array=( 1337 -13 -666 -208 -408 )
$ sum=$(IFS=+; echo "$((${array[*]}))")
$ echo "$sum"
42

Pro: No loop, no subshell!

优点:没有循环,没有子shell!

Con: Only works with integers

缺点:仅适用于整数

Edit (2012/12/26).

编辑(2012/12/26)。

As this post got bumped up, I wanted to share with you another funny way, using dc, which is then not restricted to just integers:

随着这篇文章的出现,我想与您分享另一种有趣的方法,使用dc,然后它不仅限于整数:

$ dc <<< '[+]sa[z2!>az2!>b]sb1 2 3 4 5 6 6 5 4 3 2 1lbxp'
42

This wonderful line adds all the numbers. Neat, eh?

这条美妙的线将所有数字相加。整洁,嗯?

If your numbers are in an array array:

如果您的数字在数组中array

$ array=( 1 2 3 4 5 6 6 5 4 3 2 1 )
$ dc <<< '[+]sa[z2!>az2!>b]sb'"${array[*]}lbxp"
42

In fact there's a catch with negative numbers. The number '-42' should be given to dcas _42, so:

事实上,有一个负数问题。数字 '-42' 应该给dcas _42,所以:

$ array=( -1.75 -2.75 -3.75 -4.75 -5.75 -6.75 -7.75 -8.75 )
$ dc <<< '[+]sa[z2!>az2!>b]sb'"${array[*]//-/_}lbxp"
-42.00

will do.

会做。

Pro: Works with floating points.

优点:适用于浮点。

Con: Uses an external process (but there's no choice if you want to do non-integer arithmetic — but dcis probably the lightest for this task).

缺点:使用外部进程(但如果你想进行非整数运算就别无选择——但dc可能是这个任务中最轻的)。

回答by F-3000

My code (which I actually utilize) is inspired by answer of gniourf_gniourf. I personally consider this more clear to read/comprehend, and to modify. Accepts also floating points, not just integers.

我的代码(我实际使用的)的灵感来自gniourf_gniourf的答案。我个人认为这更易于阅读/理解和修改。还接受浮点数,而不仅仅是整数。

Sum values in array:

数组中的总和值:

arr=( 1 2 3 4 5 6 7 8 9 10 )
IFS='+' sum=$(echo "scale=1;${arr[*]}"|bc)
echo $sum # 55

With small change, you can get the average of values:

通过小的变化,您可以获得值的平均值:

arr=( 1 2 3 4 5 6 7 8 9 10 )
IFS='+' avg=$(echo "scale=1;(${arr[*]})/${#arr[@]}"|bc)
echo $avg # 5.5

回答by Amelia Hartman

I'm a fan of brevity, so this is what I tend to use:

我是简洁的粉丝,所以这是我倾向于使用的:

IFS="+";bc<<<"${array[*]}"

It essentially just lists the data of the array and passes it into BC which evaluates it. The "IFS" is the internal field separate, it essentially specifies how to separate arrays, and we said to separate them with plus signs, that means when we pass it into BC, it receives a list of numbers separated by plus signs, so naturally it adds them together.

它本质上只是列出数组的数据并将其传递给 BC 进行评估。“IFS”是内部的分隔字段,它本质上指定了如何分隔数组,我们说用加号分隔它们,也就是说当我们把它传入BC时,它会收到一个用加号分隔的数字列表,所以很自然它将它们加在一起。

回答by Banana

gniourf_gniourf's answeris excellent since it doesn't require a loop or bc. For anyone interested in a real-world example, here's a function that totals all of the CPU cores reading from /proc/cpuinfo without messing with IFS:

gniourf_gniourf 的答案非常好,因为它不需要循环或 bc。对于任何对实际示例感兴趣的人,这里有一个函数,它可以汇总从 /proc/cpuinfo 读取的所有 CPU 内核,而不会与 IFS 混淆:

# Insert each processor core count integer into array
cpuarray=($(grep cores /proc/cpuinfo | awk '{print }'))
# Read from the array and replace the delimiter with "+"
# also insert 0 on the end of the array so the syntax is correct and not ending on a "+"
read <<< "${cpuarray[@]/%/+}0"
# Add the integers together and assign output to $corecount variable
corecount="$((REPLY))"
# Echo total core count
echo "Total cores: $corecount"

I also found the arithmetic expansion works properly when calling the array from inside the double parentheses, removing the need for the read command:

我还发现当从双括号内调用数组时,算术扩展可以正常工作,不需要读取命令:

cpuarray=($(grep cores /proc/cpuinfo | awk '{print }'))
corecount="$((${cpuarray[@]/%/+}0))"
echo "Total cores: $corecount"

Generic:

通用的:

array=( 1 2 3 4 5 )
sum="$((${array[@]/%/+}0))"
echo "Total: $sum"

回答by agc

Another dc& bashmethod:

另一种dc&bash方法:

arr=(1 3.88 7.1 -1)
dc -e "0 ${arr[*]/-/_} ${arr[*]/*/+} p"

Output:

输出:

10.98

The above runs the expression 0 1 3.88 7.1 _1 + + + + pwith dc. Note the dummy value 0because there's one too many +s, and also note the usual negative number prefix -must be changed to _in dc.

上面的表达式0 1 3.88 7.1 _1 + + + + pdc. 请注意虚拟值,0因为+s太多了,还要注意通常的负数前缀-必须更改为_in dc

回答by rashedcs

A simple way

一个简单的方法

function arraySum 
{
        sum=0
        for i in ${a[@]};
        do
              sum=`expr $sum + $i`  
        done
        echo $sum
}

a=(7 2 3 9)
echo -n "Sum is = " 
arraySum ${a[@]}

回答by Alexei Grochev

I find this very simple using an increasing variable:

我发现使用递增变量非常简单:

result2=0
for i  in ${lineCoffset[@]};
do
    result2=$((result2+i))  
done
echo $result2