работа с до н.э. - PullRequest
       32

работа с до н.э.

0 голосов
/ 07 декабря 2011

пытаясь суммировать элементы в массиве, используя 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 ]

1 голос
/ 08 декабря 2011

В истинном духе 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

Все это предполагает, что входной файл "правильно сформирован", без искаженных строк или лишних пробелов.

1 голос
/ 07 декабря 2011

Я не уверен, требуется ли вам использовать 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
0 голосов
/ 07 декабря 2011

Удалить слово cat из строки done < cat foo.txt.

Обновление: Удалите также все пустые строки из входного файла.

...