Tengo un archivo que contiene dos columnas y 10 millones de filas. La primera columna contiene muchos valores repetidos, pero hay un valor distinto en la columna 2. Quiero eliminar las filas repetidas y quiero conservar solo una usando awk
. Nota: el archivo está ordenado con valores en la columna 1. Por ejemplo:
1.123 -4.0
2.234 -3.5
2.234 -3.1
2.234 -2.0
4.432 0.0
5.123 +0.2
8.654 +0.5
8.654 +0.8
8.654 +0.9
.
.
.
.
Rendimiento esperado
1.123 -4.0
2.234 -3.5
4.432 0.0
5.123 +0.2
8.654 +0.5
.
.
.
.
Respuesta1
Algunas maneras:
awk
awk '!a[$1]++' file
Esta es una forma muy condensada de escribir esto:
awk '{if(! a[$1]){print; a[$1]++}}' file
Entonces, si el primer campo actual (
$1
) no está en laa
matriz, imprima la línea y agregue el primer campo aa
. La próxima vez que veamos ese campo, estará en la matriz y, por lo tanto, no se imprimirá.perla
perl -ane '$k{$F[0]}++ or print' file
o
perl -ane 'print if !$k{$F[0]}++' file
Este es básicamente el mismo que el
awk
anterior. Esto-n
hace que Perl lea el archivo de entrada línea por línea y aplique el script proporcionado por-e
a cada línea. Dividirá-a
automáticamente cada línea en espacios en blanco y guardará los campos resultantes en la@F
matriz. Finalmente, el primer campo se agrega al%k
hash y, si aún no está allí, se imprime la línea. Lo mismo podría escribirse comoperl -e 'while(<>){ @F=split(/\s+/); print unless defined($k{$F[0]}); $k{$F[0]}++; }' file
Coreutils
rev file | uniq -f 1 | rev
Este método funciona invirtiendo primero las líneas de
file
modo que si una línea es 12 345 ahora será 543 21. Luego usamosuniq -f 1
para ignorar el primer campo, es decir, la columna en la que se encuentra 543. Hay campos dentrofile
. Usaruniq
aquí tiene el efecto de filtrar cualquier línea duplicada, manteniendo solo 1 de cada una. Por último volvemos a colocar las líneas en su orden original con otro reverso.Tipo GNU (comosugiriópor @StéphaneChazelas)
sort -buk1,1
La
-b
bandera ignora los espacios en blanco iniciales y los-u
medios imprimen solo campos únicos. Lo inteligente es el-k1,1
. La-k
bandera establece el campo por el que ordenar. Toma el formato general,-k POS1[,POS2]
lo que significa que solo debe mirar los camposPOS1
a través de POS2 al ordenar. Entonces,-k1,1
significa mirar solo el primer campo. Dependiendo de tus datos, es posible que desees agregar también una de estas opciones:-g, --general-numeric-sort compare according to general numerical value -n, --numeric-sort compare according to string numerical value
Respuesta2
Si la primera columna siempre tiene 5 caracteres, simplemente puede usar uniq
:
uniq -w 5 file
Si no, utilice awk
:
awk '$1!=a{print $0; a=$1}' file
El primero definitivamente sería más rápido con un archivo enorme.