Результат

Результат

У меня есть такой файл:

paper 3
paper 6
eraser 2
pencil 9
pencil 44
pencil 1

Я хотел бы суммировать строки с общим первым полем, например так:

paper 9
eraser 2
pencil 54

Есть ли симпатичный однострочный способ сделать это с помощью стандартных утилит Unix? Или даже не очень стандартных утилит Unix.

решение1

Взгляните на это:

$ echo "$a"
paper 3
paper 6
eraser 2
pencil 9
pencil 44
pencil 1

$ awk '{a[$1]=a[$1]+$2}END{for (i in a) print i,a[i]}' <(echo "$a")
pencil 54
eraser 2
paper 9

Замените <(echo "$a)на свой file:

$ awk '{a[$1]=a[$1]+$2}END{for (i in a) print i,a[i]}' file

решение2

С не совсем стандартной утилитойGNU-датамаш

$ datamash --whitespace groupby 1 sum 2 < file
paper   9
eraser  2
pencil  54

или более кратко

$ datamash -Wg 1 sum 2 < file
paper   9
eraser  2
pencil  54

решение3

Если нас интересует порядок печати, то мы можем сделать так:

perl -lane '$h{$F[0]}+=$F[1]; $h[-1+keys%h]=$F[0]; END{print "$_ $h{$_}" for @h}'

Идея заключается в том, чтобы поддерживать текущие суммы конкретного элемента в хэше %hи порядок, в котором конкретный элемент был виден в @hмассиве. В конце файла мы просто печатаем хэш (ключ+значение), но берем порядок из @hмассива.

Результат

paper 9
eraser 2
pencil 54

решение4

Вот не очень симпатичная строчка на awk:

awk '{ if (prev && prev != $1) { print prev, sum; sum = 0 }; sum += $2; prev = $1 } END { print prev, sum }' < file.txt

Он требует, чтобы строки с одинаковым значением в первом поле были сгруппированы вместе. Если это не так, вы можете sort file.txt | awk ....

Связанный контент