Eliminar toda la fila de un archivo si se repite la primera columna

Eliminar toda la fila de un archivo si se repite la primera columna

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:

  1. 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 la amatriz, imprima la línea y agregue el primer campo a a. La próxima vez que veamos ese campo, estará en la matriz y, por lo tanto, no se imprimirá.

  2. 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 awkanterior. Esto -nhace que Perl lea el archivo de entrada línea por línea y aplique el script proporcionado por -ea cada línea. Dividirá -aautomáticamente cada línea en espacios en blanco y guardará los campos resultantes en la @Fmatriz. Finalmente, el primer campo se agrega al %khash y, si aún no está allí, se imprime la línea. Lo mismo podría escribirse como

    perl -e 'while(<>){
                @F=split(/\s+/); 
                print unless defined($k{$F[0]}); 
                $k{$F[0]}++;
             }' file
    
  3. Coreutils

    rev file | uniq -f 1 | rev
    

    Este método funciona invirtiendo primero las líneas de filemodo que si una línea es 12 345 ahora será 543 21. Luego usamos uniq -f 1para ignorar el primer campo, es decir, la columna en la que se encuentra 543. Hay campos dentro file. Usar uniqaquí 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.

  4. Tipo GNU (comosugiriópor @StéphaneChazelas)

    sort -buk1,1
    

    La -bbandera ignora los espacios en blanco iniciales y los -umedios imprimen solo campos únicos. Lo inteligente es el -k1,1. La -kbandera establece el campo por el que ordenar. Toma el formato general, -k POS1[,POS2]lo que significa que solo debe mirar los campos POS1a través de POS2 al ordenar. Entonces, -k1,1significa 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.

información relacionada