Como obter a soma dos valores na coluna com base nas variáveis em outra coluna separadamente? [duplicado]

4

Eu tenho dados de tabela como abaixo

abc 1   1   1
bcd 2   2   4
bcd 12  23  3
cde 3   5   5
cde 3   4   5
cde 14  2   25

Eu quero a soma dos valores em cada coluna com base nas variáveis da primeira coluna e o resultado desejado é o seguinte:

abc 1   1   1
bcd 14  25  7
cde 20  11  35

Eu usei o comando awk assim

awk -F"\t" '{for(n=2;n<=NF; ++n)a[$1]+=$n}END{for(i in a ) print i, a[i] }' tablefilepath

e eu tenho um resultado abaixo:

abc 3
bcd 46
cde 66

Acho que o final do meu código está errado, mas não sei como consertar isso. Preciso de algumas instruções para corrigir o código.

    
por awkprob 27.11.2018 / 07:05

3 respostas

4

Você estava bem perto. Você vê o que você estava fazendo errado, não é? Você estava mantendo um total para cada valor de coluna 1, quando você deveria ter mantido três.

Isso é semelhante a resposta de Inian , mas trivialmente extensível para lidar com qualquer número de colunas:

awk -F"\t" '{for(n=2;n<=NF; ++n) a[$1][n]+=$n}
        END {for(i in a) {
                printf "%s", i
                for (n=2; n<=4; ++n) printf "\t%s", a[i][n]
                printf "\n"
             }
        }'

Em vez de manter três matrizes, como a resposta de Inian, mantém uma matriz bidimensional.

    
por 27.11.2018 / 07:27
4

Desde que seu arquivo seja delimitado por tabulação, o datamash é adequado para isso.

$ datamash groupby 1 sum 2 sum 3 sum 4 < tablefilepath
abc     1       1       1
bcd     14      25      7
cde     20      11      35

O Datamash também pode funcionar com guias diferentes, se você especificar -t <delimiter> . Mas as guias parecem mais próximas da entrada de exemplo que você forneceu.

O Datamash não funciona se a sua entrada for delimitada por espaços em branco arbitrários (ou seja, possíveis espaços múltiplos destinados a "parecerem" um separador). Ainda assim, mesmo que seja assim que seus dados são, eles são facilmente inseridos no formato esperado pelo datamash:

sed -i 's/ \+/\t/g' tablefilepath
    
por 27.11.2018 / 07:12
2

Usando awk resumindo as colunas 2-4 com base em 1.

awk -v FS="\t" -v OFS="\t" '{ col1[$1]+=$2; col2[$1]+=$3; col3[$1]+=$4; next } END { for ( i in col1) print i, col1[i], col2[i], col3[i]  }' file
    
por 27.11.2018 / 07:17