Resumindo linhas com um campo comum

0

Eu tenho um arquivo como este:

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

Eu gostaria de resumir as linhas com um primeiro campo comum, assim:

paper 9
eraser 2
pencil 54

Existe um forro bonitinho para fazer isso usando utilitários padrão do Unix? Ou até utilitários Unix não tão padrão.

    
por Snowball 12.04.2017 / 02:01

4 respostas

2

Dê uma olhada nisso:

$ 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

Substitua <(echo "$a) pelo seu file :

$ awk '{a[$1]=a[$1]+$2}END{for (i in a) print i,a[i]}' file
    
por 12.04.2017 / 02:23
2

Com o utilitário não tão padrão datamash do GNU

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

ou mais sucintamente

$ datamash -Wg 1 sum 2 < file
paper   9
eraser  2
pencil  54
    
por 12.04.2017 / 02:24
2

Se nos preocupamos com a ordem de impressão, podemos fazer isso:

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

A idéia é manter as somas em execução de um item específico no hash %h e a ordem em que o item específico foi visto na matriz @h . No final do arquivo, apenas imprimimos o hash (chave + valor), mas pegamos a ordem de @h array.

Resultado

paper 9
eraser 2
pencil 54
    
por 12.04.2017 / 06:56
1

Aqui está um forro não tão fofo no awk:

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

Requer que as linhas com o mesmo valor no primeiro campo sejam agrupadas. Se este não for o caso, você pode sort file.txt | awk ... .

    
por 12.04.2017 / 02:18