Eliminar toda la fila en un file si se repite la primera columna

Tengo un file 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 mantener solo una usando awk . Nota: el file está orderado 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 . . . . 

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 a matriz, 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. Perl

     perl -ane '$k{$F[0]}++ or print' file 

    o

     perl -ane 'print if !$k{$F[0]}++' file 

    Esto es básicamente lo mismo que el awk one. El -n hace que perl lea el file de input línea por línea y aplique el script proporcionado por -e a cada línea. El -a dividirá automáticamente cada línea en espacios en blanco y saveá los campos resultantes en la matriz @F . Finalmente, el primer campo se agrega al %k hash y si no está ya 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 las líneas en el file modo que si una línea es 12 345, ahora será 543 21. Entonces usamos uniq -f 1 para ignorar el primer campo, es decir, la columna en la que 543 está . Hay campos dentro del file . Usar uniq aquí tiene el efecto de filtrar cualquier línea duplicada, manteniendo solo 1 de cada una. Por último, volvemos a poner las líneas en su order original con otro reverso.

  4. Tipo GNU (según lo sugerido por @ StéphaneChazelas)

     sort -buk1,1 

    El indicador -b ignora el espacio en blanco inicial y el -u significa que solo imprime campos únicos. El bit inteligente es el -k1,1 . El -k establece el campo para orderar. Toma el formatting general de -k POS1[,POS2] que significa que solo mira los campos POS1 a POS1 al orderar. Entonces, -k1,1 significa solo mirar el primer campo. Según sus datos, es posible que también desee agregar una de estas opciones:

      -g, --general-numeric-sort compare according to general numerical value -n, --numeric-sort compare according to string numerical value 

Si la primera columna tiene siempre 5 caracteres, simplemente puede usar uniq :

 uniq -w 5 file 

Si no, usa awk :

 awk '$1!=a{print $0; a=$1}' file 

El primero definitivamente sería más rápido con un file enorme.