Unix Shell脚本一起添加数组元素

时间:2012-11-29 21:43:30

标签: arrays bash shell unix sh

我对数组知之甚少,但我正在尝试添加由“read -a”命令中的用户输入定义的数组元素。

8 个答案:

答案 0 :(得分:10)

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

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

如,

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

Pro:没有循环,没有子shell!

Con:仅适用于整数

编辑(2012/12/26)。

随着这篇文章的提升,我想用另一种有趣的方式与你分享,使用dc,然后不仅限于整数:

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

这条精彩的线条增添了所有数字。干净,嗯?

如果您的号码在数组中array

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

事实上,这是一个带负数的问题。数字&#39; -42&#39;应该dc作为_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

会做的。

Pro:适用于浮点。

Con:使用外部进程(但如果你想进行非整数运算,则别无选择 - 但dc可能是此任务中最轻的一个。)

答案 1 :(得分:9)

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

答案 2 :(得分:6)

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

数组中的和值:

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

如果变化很小,您可以获得平均值:

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

答案 3 :(得分:3)

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

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

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

答案 4 :(得分:3)

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

# Insert each processor core count integer into array
cpuarray=($(grep cores /proc/cpuinfo | awk '{print $4}'))
# 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"

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

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

通用:

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

答案 5 :(得分:1)

另一个dc&amp; bash方法:

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

输出:

10.98

上面使用0 1 3.88 7.1 _1 + + + + p运行表达式dc。请注意虚拟值0,因为+太多-,并且还注意通常的负数前缀_必须更改为dc new DateTime.fromMillisecondsSinceEpoch(1516920700513); 1}}。

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

arr=(1 2 3) //or use `read` to fill the array
echo Sum of array elements: $(( ${arr[@]/%/ +} 0))
Sum of array elements: 6

说明:

  1. "${arr[@]/%/ +}" 将返回 1 + 2 + 3 +
  2. 通过在末尾添加额外的零,我们将得到 1 + 2 + 3 + 0
  3. 通过像这样$(( "${arr[@]/%/ +} 0"))用 BASH 的数学运算包装这个字符串,它将返回总和

这可用于其他数学运算。

  1. 对于减法,只需使用 - 代替
  2. 对于乘法,使用 *1 而不是 0

也可以与逻辑运算符一起使用。

  1. BOOL AND Example - 检查所有项目是否为真 (1)

    arr=(1 0 1)

    if [[ $((${arr[@]/%/ &} 1)) -eq 1 ]]; then echo "yes"; else echo "no"; fi

    这将打印:否

  2. BOOL OREXAMPLE - 检查任何项目是否为真 (1)

    arr=(1 0 0)

    if [[ $((${arr[@]/%/ |} 0)) -eq 1 ]]; then echo "yes"; else echo "no"; fi

    这将打印:是