
Todavía estoy aprendiendo a programar y he probado muchas cosas pero no puedo conseguir el formato correcto. tengo undelimitado por tabulacionesarchivo con 17 columnas y muchas (alrededor de 50.000) filas. El archivo ya está ordenado por la primera columna. Quiero fusionar filas que tienen la misma primera columna (A), pero las otras 16 columnas son diferentes y quiero mantener toda la información en una fila, preferiblemente en la misma columna conpunto y coma;como delimitador entre ellos. Quiero mantener la pestaña como delimitador en el archivo de salida. Muchas gracias por las respuestas y si también pudieras explicar la respuesta en la que me equivoqué, sería aún mejor :).
Lo he intentado hasta ahora:
awk -F'\t' 'NF>1{a[$1] = a[$1]";"$2}END{for(i in a){print i""a[i]}}' filename.txt
perl -F',' -anle 'next if /^$/;$h{$F[0]} = $h{$F[0]}.", ".$F[1];
END{print $_,$h{$_},"\n" for sort keys %h}' filename.txt
FORMATO DE ARCHIVO (otras 15 columnas tienen el mismo formato que la columna B)
A B C
123 fvv ggg
123 kjf ggg
123 ccd att
567 abc gst
567 abc hgt
879 ttt tyt
El resultado que quiero (necesito las 17 columnas y para las columnas 2 a 16 necesito el mismo resultado que en las columnas B y C). Todos los casos de B deben estar debajo de B y todos los casos de C deben estar debajo de C y todos los casos de D deben estar debajo de D, etc. Entonces, la salida tiene 17 columnas al igual que la entrada y en lugar de 50,000 filas, ahora debería tener alrededor de 20,000. , porque hay muchas repeticiones para la columna 1 (para este archivo en particular):
A B C
123 fvv;kjf;ccd ggg;ggg;att
567 abc;abc gst;hgt
879 ttt lll
Respuesta1
awk '{
if(NR!=1){a[$1]=$2";"a[$1]}
else print $0}
END{
n = asorti(a, b);
for (n in b) {
print b[n],a[b[n]]
}
}'
Respuesta2
Una solución Perl:
$ perl -F"\t" -anle 'if($.==1){print; next} push @{$k{$F[0]}},@F[1..$#F];
END{print "$_\t" . join(";",@{$k{$_}}) for sort keys(%k)}' file
A B
123 fvv;kjf;ccd
567 abc;abc
879 ttt
Esto puede funcionar en un número arbitrario de campos. Sin embargo, requiere cargar bastantes cosas en la memoria y eso podría ser un problema si el archivo es grande.
En cuanto a dónde salió mal, no podemos decírselo a menos que explique lo que realmente sucedió, pero, en lo que se me ocurre, su intento de Perl fallaría porque:
- Está utilizando
-F,
el cual establece el separador de campo en una coma cuando su entrada tiene pestañas. - Estás usando
-l
yprint "foo\n"
. Ya-l
agrega una nueva línea a cada llamada de impresión, por lo que tendrá varias líneas en blanco. - Está utilizando
$h{$F[0]}.", ".$F[1];
para agregar, por lo que la primera vez que se ejecuta y$h{$F[0]}
no está definido, agregará un extra,
al comienzo de su valor almacenado. - Sólo estás mirando el segundo campo, ignorando todos los demás.
De manera similar, su testamento awk
fallará porque:
- Está imprimiendo
foo""bar
, lo que concatenará la salida sin espacios entre cada campo. Quiereprint foo,bar
y también quiereOFS="\t"
una salida separada por tabulaciones. - Sólo estás mirando el segundo campo, ignorando todos los demás.
Respuesta3
Disculpas por esta frase, pero aquí va:
awk 'BEGIN{FS="\t"} {for(i=2; i<=NF; i++) { if (!a[$1]) a[$1]=$1FS$i ;else a[$1]=a[$1]";"$i};if ($1 != old) b[j++] = a[old];old=$1 } END{for (i=0; i<j; i++) print b[i] }' 1
123 fvv ;kjf;ccd
567 abc;abc
879 ttt
Respuesta4
awk '
function p(n,A){
s = n
for(i=2;i<=NF;i++){
s = s "\t" A[i]
A[i] = $i
}
if(n)
print s
}
NR==1{
print
next
}
$1==n{
for(i=2;i<=NR;i++)
A[i] = A[i] ";" $i
next
}
{
p(n,A)
n = $1
}
END{
p(n,A)
}
' file