从数组条目中计算特定字段的总和

Computing sum of specific field from array entries

我有一个数组trf。想要计算每个数组条目中第二个元素的总和。

数组内容示例

trf=( "2 13 144" "3 21 256" "5 34 389" )

这是当前的实现,但我觉得它不够健壮。例如,它在每个数组条目中的任意数量的元素(但从一个数组元素到另一个数组元素被认为是常量)失败。

   cnt=0
   m=${#trf[@]}
   while (( cnt < m )); do
     while read -r one two three
     do
       sum+="$two"+
     done <<< $(echo ${array[$count]})
     let count=$count+1
   done

   sum+=0
   result=`echo "$sum" | /usr/bin/bc -l`

你把事情搞得太复杂了。像

#!/usr/bin/env bash
trf=( "2 13 144" "3 21 256" "5 34 389" )
declare -i sum=0 # Integer attribute; arithmetic evaluation happens when assigned
for (( n = 0; n < ${#trf[@]}; n++)); do
    read -r _ val _ <<<"${trf[n]}"
    sum+=$val
done
printf "%d\n" "$sum"

在纯 bash 中,或者只使用 awk(如果你的真实数据中有浮点数,这很方便):

printf "%s\n" "${trf[@]}" | awk '{ sum +=  } END { print sum }'

您可以使用 printf 打印整个数组,每行一个条目。对于这样的输入,一个循环 (while read) 就足够了。您甚至可以使用 cuttr 完全跳过循环来构建 bc 命令。 echo 0 在那里 bc 可以处理空数组和由 tr.

插入的尾随 +
{ printf %s\n "${trf[@]}" | cut -d' ' -f2 | tr \n +; echo 0; } | bc -l

对于您的示例,这会生成打印 68 (= 13+21+34+0).

试试这个 printf + awk 组合:

$ printf '%s\n' "${trf[@]}" | awk '{print }{a+=}END{print "sum:", a}'
13
21
34
sum: 68

哦,Shawn 已经建议了。然后循环:

$ for item in "${trf[@]}"; do
    echo $item
done | awk '{print }{a+=}END{print "sum:", a}'
13
21
34
sum: 68

对于相对较小的数组,for/while 双循环应该没问题 re: 性能;将最终总和放在 $result 变量中(如 OP 的代码中所示):

result=0

for element in "${trf[@]}"
do
    while read -r a b c
    do 
        ((result+=b))
    done <<< "${element}"
done

echo "${result}"

这会生成:

68

对于更大的数据集,我可能会选择仅 awk 的解决方案之一(出于性能原因)。