![Eliminar líneas con el primer campo/columna repetido de un archivo grande](https://rvso.com/image/164735/Eliminar%20l%C3%ADneas%20con%20el%20primer%20campo%2Fcolumna%20repetido%20de%20un%20archivo%20grande.png)
Tengo un archivo muy grande (fragmento a continuación). Necesito eliminar cualquier línea donde el número de la primera columna no aumente consecutivamente desde la línea anterior.
Por ejemplo, quiero conservar la primera línea de mi fragmento, donde el identificador en la primera columna es " 40812
." Luego quiero conservar la fila donde " 40813
" está en la primera columna (línea 3 en mi ejemplo) y luego la fila que comienza con " 40814
", y así sucesivamente. Quiero eliminar cualquier línea que viole esta sucesión, como la segunda fila.
He buscado aquí preguntas/respuestas anteriores en busca de posibles soluciones y hasta ahora no he tenido éxito. Una solución que ha aparecido en varias preguntas es:
awk -F',' ' '!seen[$1]++ myFile
Adapté otra solución que vi como:
sort -t':' -k 1,1 -u myFile
Si alguien pudiera decirme en qué me estoy equivocando, se lo agradecería mucho. No tengo mucha experiencia con la manipulación de archivos.
40812 20406.000000 0.843859468 1083.209050130 -994.562279080 -993.349611938 22.120868921
40829 20414.500000 0.891283743 1144.084593627 -994.539001565 -993.349739827 21.177788019
40813 20406.500000 0.829362077 1064.599666089 -994.546948121 -993.348764740 22.087239027
40830 20415.000000 0.889606427 1141.931529727 -994.537943593 -993.350242614 21.282490969
40814 20407.000000 0.822524589 1055.822814442 -994.540118434 -993.348757318 22.083606005
40831 20415.500000 0.875230513 1123.478077086 -994.523844766 -993.350421831 20.606467962
40815 20407.500000 0.823511602 1057.089780943 -994.541681744 -993.349315083 22.432111979
40832 20416.000000 0.846150258 1086.149592126 -994.494220141 -993.349798791 22.309054136
40816 20408.000000 0.824550451 1058.423286012 -994.543159511 -993.349731194 22.481428146
40833 20416.500000 0.811604775 1041.805740021 -994.458563132 -993.348626225 21.118428946
40834 20417.000000 0.787796672 1011.244783236 -994.434062658 -993.347887110 20.963790894
40817 20408.500000 0.819160081 1051.504008955 -994.537767061 -993.349702160 22.268819809
40835 20417.500000 0.784857495 1007.471947645 -994.431441227 -993.348167742 20.731789112
40818 20409.000000 0.807571275 1036.628191427 -994.525675417 -993.349169067 22.332761049
40836 20418.000000 0.799208319 1025.893192994 -994.446595759 -993.348938468 21.268665075
40819 20409.500000 0.797104599 1023.192780242 -994.514563564 -993.348491176 22.622548103
40837 20418.500000 0.819797939 1052.322786256 -994.467698852 -993.349417295 21.013041973
40820 20410.000000 0.796605925 1022.552664951 -994.513928312 -993.348319789 22.193170071
Respuesta1
Este es exactamente el tipo de cosas en las que awk
sobresale:
$ awk '{ if(NR==1 || $1 == last+1){print; last=$1}}' file
40812 20406.000000 0.843859468 1083.209050130 -994.562279080 -993.349611938 22.120868921
40813 20406.500000 0.829362077 1064.599666089 -994.546948121 -993.348764740 22.087239027
40814 20407.000000 0.822524589 1055.822814442 -994.540118434 -993.348757318 22.083606005
40815 20407.500000 0.823511602 1057.089780943 -994.541681744 -993.349315083 22.432111979
40816 20408.000000 0.824550451 1058.423286012 -994.543159511 -993.349731194 22.481428146
40817 20408.500000 0.819160081 1051.504008955 -994.537767061 -993.349702160 22.268819809
40818 20409.000000 0.807571275 1036.628191427 -994.525675417 -993.349169067 22.332761049
40819 20409.500000 0.797104599 1023.192780242 -994.514563564 -993.348491176 22.622548103
40820 20410.000000 0.796605925 1022.552664951 -994.513928312 -993.348319789 22.193170071
O jugar un poco al golf:
$ awk '(NR==1 || $1 == last+1) && last=$1' file
40812 20406.000000 0.843859468 1083.209050130 -994.562279080 -993.349611938 22.120868921
40813 20406.500000 0.829362077 1064.599666089 -994.546948121 -993.348764740 22.087239027
40814 20407.000000 0.822524589 1055.822814442 -994.540118434 -993.348757318 22.083606005
40815 20407.500000 0.823511602 1057.089780943 -994.541681744 -993.349315083 22.432111979
40816 20408.000000 0.824550451 1058.423286012 -994.543159511 -993.349731194 22.481428146
40817 20408.500000 0.819160081 1051.504008955 -994.537767061 -993.349702160 22.268819809
40818 20409.000000 0.807571275 1036.628191427 -994.525675417 -993.349169067 22.332761049
40819 20409.500000 0.797104599 1023.192780242 -994.514563564 -993.348491176 22.622548103
40820 20410.000000 0.796605925 1022.552664951 -994.513928312 -993.348319789 22.193170071
Explicación
if(NR==1 || $1 == last+1)
:NR
es el número de línea actual. Por lo tanto,NR == 1
solo será cierto al leer la primera línea del archivo. Necesitamos esto para que siempre imprimamos la primera línea. Entonces,$1 == last +1
será verdadero si el primer campo de la línea ($1
) es igual al valor almacenado en la variablelast
más 1. En conjunto, esto significa "si esta es la última línea o si el primer campo es igual al último + 1", lo cual define sus líneas de destino.print; last=$1
: Si cualquiera de las dos condiciones explicadas anteriormente es verdadera, imprima la línea y establezca el valor delast
para que sea el primer campo deestelínea para que podamos procesar la siguiente.