从数组项中计算特定字段的和



我有一个数组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 "%dn" "$sum"

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

printf "%sn" "${trf[@]}" | awk '{ sum += $2 } 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 '%sn' "${trf[@]}" | awk '{print $2}{a+=$2}END{print "sum:", a}'
13
21
34
sum: 68

哦,Shawn已经建议过了。然后加上loop:

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

对于相对较小的数组,for/while双循环应该是ok的;将最后的总和放在$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的解决方案之一(出于性能原因)。

相关内容

  • 没有找到相关文章

最新更新