Combinando texto através de linhas contíguas com chave iguais?

1

Eu tenho um arquivo CSV de entrada que se parece com isso:

john,Hello my name
john,is John
katie,Whereas my
katie,name is Katie
bob,And I am Bob.

O arquivo é ordenado de modo que os nomes (na primeira coluna) sejam contíguos e o texto (a segunda coluna) seja ordenado logicamente.

Existe uma maneira padronizada de "agrupar por" (usando a terminologia SQL) a primeira coluna e concatenar a segunda coluna?

Minha saída desejada é:

john,Hello my name is John
katie,Whereas my name is Katie
bob,And I am Bob.
    
por Philip 15.02.2016 / 23:58

3 respostas

0

Não há uma ferramenta padrão para isso, não. Esta tarefa é bastante adequada para o awk: leia linhas uma por uma, salve o primeiro campo e acumule o segundo campo e imprima o resultado se o primeiro campo for alterado. A dificuldade principal (menor) é que o resultado também deve ser impresso quando a última linha é alcançada.

awk -F, '
    1 {current = $1; sub(/^[^,]*,/,"")}
    current == previous {acc = acc " " $0; next}
    NR != 1 {print previous "," acc}
    1 {previous = current; acc = $0}
    END {if (NR) print previous "," acc}'
    
por 16.02.2016 / 01:05
1

O conhecimento avançado da duração de cada bloco nos poupa da menor complicação de lidar com uma condição de contorno que, de outra forma, exigiria um bloco END de funcionalidade replicada.

Eu não defendo esta abordagem em favor da resposta aceita por Gilles. Eu apenas a apresento para demonstrar uma abordagem alternativa que, ao lidar com problemas complicados (não sendo um deles), poderia produzir uma redução significativa na complexidade (ao custo da E / S e, possivelmente, da memória).

a é uma matriz indexada por nome de comprimentos de bloco. n é o número de linhas restantes em um bloco:

awk -F, '
    FNR==NR  {a[$1]++; next}
          n  {print " "$2}
         !n  {print; n=a[$1]}
       !--n  {print "\n"}
' ORS= data data
    
por 16.02.2016 / 09:03
-1
awk -F, '{a[$1]=a[$1]? a[$1]" "$2 : $2;}END{for (i in a)print i, a[i];}' OFS=, filename
    
por 16.02.2016 / 00:15