-1

尝试使用 bc 对数组中的元素求和,我有一个包含名称和它们的值的文件,如果名称出现 3 次,我应该将其值乘以 3,然后找到所有元素的总和,我看到标准输入错误

$ cat foo.txt

max 2.3 
henry 3
fransis 4.5
max 2.3
henry 3
max 2.3

它应该显示在终端上

max 6.9
henry 6 
fransis 4.5

然后

total 17.9
declare -A array

while read name value; do

     array[$name]=$( echo "${array[$name]:-0} + $value" | bc )

done < cat foo.txt

for name in "${!array[@]}"; do

     echo "$name ${array[$name]}"

done
4

3 回答 3

1

我不确定您是否需要使用bc,但这可以通过以下awk命令完成:

awk '{names[$1]=$1;vals[$1]+=$2} END {for(i in names){sum+=vals[i];print i, vals[i]}; print "total " sum}' foo.txt
于 2011-12-07T16:25:34.260 回答
1

本着真正的 bash 精神,这里有一系列管道命令来实现这一点:)

echo 'max 2.3
henry 3
fransis 4.5
max 2.3
henry 3
max 2.3' | \
sort | \
uniq -c | \
while read count name value
  do echo "$name" $(bc <<< "$count * $value")
done | \
sort -r -k 2

sort | uniq -c将计算相同行的数量并生成如下列表:

1 fransis 4.5
2 henry 3
3 max 2.3

该列表被传递给一次while读取 3 个值的循环 ( read count name value)

对于每组 3 个值,它会打印名称和乘法结果:

echo "$name" $(bc <<< "$count * $value")

然后对结果进行排序,使最高分位于顶部,即对第二列进行反向排序:

sort -r -k 2

这一切都假设输入文件是“格式正确的”,没有格式错误的行或额外的空格。

于 2011-12-07T23:30:59.503 回答
0

cat从行中删除单词done < cat foo.txt

更新:也从输入文件中删除任何空行。

于 2011-12-07T17:20:14.640 回答