¿Combinar texto en líneas contiguas con claves iguales?

¿Combinar texto en líneas contiguas con claves iguales?

Tengo un archivo CSV de entrada que se parece a este:

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

El archivo está ordenado de manera que los nombres (en la primera columna) sean contiguos y el texto (la segunda columna) esté ordenado de forma lógica.

¿Existe una forma estandarizada de "agrupar" (usando terminología SQL) la primera columna y concatenar la segunda columna?

Mi resultado deseado es:

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

Respuesta1

El conocimiento avanzado de la longitud de cada bloque nos ahorra la pequeña complicación de lidiar con una condición de contorno que de otro modo requeriría un bloque FINAL de funcionalidad replicada.

No defiendo este enfoque a favor de la respuesta aceptada de Gilles. Simplemente lo presento para demostrar un enfoque alternativo que, cuando se trata de problemas complicados (este no es uno de ellos), podría producir una reducción significativa de la complejidad (a costa de E/S y posiblemente de memoria).

aes una matriz de longitudes de bloque indexada por nombre. nes el número de líneas restantes en un bloque:

awk -F, '
    FNR==NR  {a[$1]++; next}
          n  {print " "$2}
         !n  {print; n=a[$1]}
       !--n  {print "\n"}
' ORS= data data

Respuesta2

No existe una herramienta estándar para eso, no. Esta tarea es bastante adecuada para awk: leer las líneas una por una, guardar el primer campo y acumular el segundo campo, e imprimir el resultado si el primer campo cambia. La principal (menor) dificultad es que el resultado también debe imprimirse cuando se llega a la última línea.

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}'

Respuesta3

awk -F, '{a[$1]=a[$1]? a[$1]" "$2 : $2;}END{for (i in a)print i, a[i];}' OFS=, filename

información relacionada