une várias linhas com base em column1

7

Eu tenho um arquivo como abaixo ..

abc, 12345
def, text and nos    
ghi, something else   
jkl, words and numbers

abc, 56345   
def, text and nos   
ghi, something else 
jkl, words and numbers

abc, 15475  
def, text and nos 
ghi, something else
jkl, words and numbers

abc, 123345
def, text and nos
ghi, something else  
jkl, words and numbers

Eu quero converter (juntar) como:

abc, 12345, 56345, 15475, 123345
def, text and nos, text and nos,text and nos,text and nos
ghi, something else, something else, something else, something else   
jkl, words and numbers, words and numbers, words and numbers, words and numbers
    
por pvkbhat 11.04.2014 / 05:47

2 respostas

8

Se você não se importa com a ordem de saída:

$ awk -F',' 'NF>1{a[$1] = a[$1]","$2};END{for(i in a)print i""a[i]}' file 
jkl, words and numbers, words and numbers, words and numbers, words and numbers
abc, 12345, 56345, 15475, 123345
ghi, something else, something else, something else, something else
def, text and nos, text and nos, text and nos, text and nos

Explicação

  • NF>1 significa que precisamos apenas processar a linha que não está em branco.
  • Salvamos todo o primeiro campo na matriz associativa a , com a chave sendo o primeiro campo, o valor é o segundo campo (ou o restante da linha). Se a chave já tiver valor, nós concatimos dois valores.
  • No bloco END , percorremos a matriz associativa a e imprimimos todas as suas chaves com o valor correspondente.

Ou usar perl manterá o pedido:

$perl -F',' -anle 'next if /^$/;$h{$F[0]} = $h{$F[0]}.", ".$F[1];
    END{print $_,$h{$_},"\n" for sort keys %h}' file
abc, 12345, 56345, 15475, 123345

def, text and nos, text and nos, text and nos, text and nos

ghi, something else, something else, something else, something else

jkl, words and numbers, words and numbers, words and numbers, words and numbers
    
por 11.04.2014 / 06:01
1

Ah, é fácil. Aqui está uma versão simples que mantém a ordem das chaves conforme elas aparecem no arquivo:

$ awk -F, '
    /.+/{
        if (!($1 in Val)) { Key[++i] = $1; }
        Val[$1] = Val[$1] "," $2; 
    }
    END{
        for (j = 1; j <= i; j++) {
            printf("%s %s\n%s", Key[j], Val[Key[j]], (j == i) ? "" : "\n");       
        }                                    
    }' file.txt

A saída deve ficar assim:

abc, 12345, 56345, 15475, 123345

def, text and nos, text and nos, text and nos, text and nos

ghi, something else, something else, something else, something else

jkl, words and numbers, words and numbers, words and numbers, words and numbers

Se você não se importar em ter uma linha extra em branco no final, basta substituir a linha printf por printf("%s %s\n\n", Key[j], Val[Key[j]]);

    
por 12.04.2014 / 06:55