Obter a soma máxima de um arquivo em 2 chaves

4

Eu tenho um arquivo como abaixo.

key1 key2  key3
a1    2    l1
a1    2.5  l2
a2    2    l2
a3    2.5  l3
a3    2.1  l4
a3    2.2  l5

Estou tentando encontrar a soma máxima possível de key2 que satisfaz a condição de que key1 e key3 ocorram apenas uma vez. Para o arquivo acima, espero que a saída seja como,

a1 2     l1
a2 2     l2
a3 2.5   l3

Se eu usar o comando abaixo,

sort -nk2 file | perl -ane '$k{$F[$1]}=$_; END{print "$k{$_}" for keys(%k)}'

Eu recebo a saída como

a2 2   l2
a1 2.5 l2
a3 2.5 l3 

No entanto, desejo obter apenas uma ocorrência de key1 e key3 na saída, além de obter a soma máxima conforme descrevi na saída esperada.

EDITAR

Eu tenho o arquivo de entrada como abaixo.

a0 11.1    l6
a0 3       l1
a1 14.0    l6
a1 2.5     l2
a2 11.1    l2
a2 2       l2
a3 13.3    l8
a3 2.1     l4
a3 2.5     l7
a4 1.6     l6
a4 1.7     l1

Como podemos ver manualmente, a saída máxima ponderada para o arquivo acima seria

a0 11.1 l6
a2 11.1  l2
a3 13.3 l8
a4 1.7  l1

De acordo com o comando awk do Gnouc, recebo a saída como

a0 11.1  l6
a1 2.5   l2
a3 13.3  l8
a4 1.7   l1

Como no comando perl de terdon, recebo a saída como

a2 2   l2
a4 1.7 l1
a3 13.3 l8

EDIT 3

a1 1 l1
a2 3 l2
a1 4 l3
a3 5 l2
a6 4 l5
a7 3 l2

Eu recebo a saída como

a3 5 l2
a6 4 l5
a7 3 l2

Como podemos ver, l2 é repetido duas vezes.

    
por Ramesh 14.07.2014 / 06:22

2 respostas

3

Parece que você deseja apenas obter a primeira ocorrência de cada key1 .

Isso produzirá sua saída esperada:

$ awk '!($1 in a){print;a[$1]}' file
a1    2    l1
a2    2    l2
a3    2.5  l3

Atualizar

Se você quiser que key1 ou key3 ocorra apenas uma vez:

$ awk '!($1 in a) && !($3 in a){print;a[$1];a[$3]}' 1.txt 
a1    2    l1
a2    2    l2
a3    2.5  l3

Atualização 2

Depois de ler seu comentário, acho que aqui está a solução:

$ sort -rnk2 file | awk '!a[$1]++' | awk '!a[$3]++'
a1 14.0    l6
a3 13.3    l8
a2 11.1    l2
a4 1.7     l1
    
por 14.07.2014 / 08:31
3

Você pode adicionar um teste ao seu script perl. Use outro hash cujas chaves são o terceiro campo e imprima cada linha somente se esse campo ainda não tiver sido visto:

$ sort -nk2 file | perl -ane '$k{$F[$1]}=$_ unless $s{$F[2]}++>0; 
                              END{print "$k{$_}" for keys(%k)}'
a3    2.5  l3
a2    2    l2
a1    2    l1

NOTA: Isto irá imprimir o cabeçalho também, mas assim será a sua abordagem e desde que você não está mostrando isso na sua saída, estou assumindo que o cabeçalho não é realmente parte do arquivo.

    
por 14.07.2014 / 13:51

Tags