与bc合作

时间:2011-12-07 16:09:23

标签: linux bash shell unix bc

尝试使用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

3 个答案:

答案 0 :(得分: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

答案 1 :(得分: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

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

答案 2 :(得分:0)

cat行中删除done < cat foo.txt字样。

更新:也从输入文件中删除所有空行。