GNU/Linux >> Tutoriales Linux >  >> Linux

Awk de diferentes líneas?

Estoy tratando de extraer algunos datos de un archivo que se actualiza constantemente y he descubierto cómo filtrar dos cadenas con grep. La salida es la siguiente:

!    total energy              =   -9744.24963670 Ry
     convergence has been achieved in 188 iterations
!    total energy              =   -9744.30001681 Ry
     convergence has been achieved in 140 iterations
!    total energy              =   -9744.33953891 Ry
     convergence has been achieved in 155 iterations
!    total energy              =   -9744.36584201 Ry
     convergence has been achieved in 164 iterations
!    total energy              =   -9744.37925372 Ry
     convergence has been achieved in 154 iterations
!    total energy              =   -9744.39185493 Ry
     convergence has been achieved in 153 iterations
!    total energy              =   -9744.39836617 Ry
     convergence has been achieved in 160 iterations

Ahora lo que me gustaría hacer es extraer de estas líneas los números de la siguiente manera:
de la línea que comienza con ! Quiero el número en la columna n.° 5 y de la siguiente línea en la salida grep quiero el número en la columna n.° 6.
A continuación, me gustaría que estos números se escribieran en un archivo separado como dos columnas separadas como:

188 -9744.24963670
140 -9744.30001681
155 -9744.33953891
164 -9744.36584201

Estaba pensando en un enfoque con awk al recorrer todos estos resultados de grep y luego mirar las líneas impares e imprimir la columna 5 y luego, para las líneas pares, imprimir la columna 6. Pero no tengo idea de cómo hacer esto.

He intentado extraer resultados individuales en variables por separado:

var1=$(grep '!' input.file | awk '{print $5}')

y

var2=$(grep 'convergence has been achieved' input.file | awk '{print $6}')

y luego traté de escribirlos en un archivo como:

echo $var1 $var2 > data.dat

Sin embargo, el resultado no es el esperado:

188                                                                                                                                                                                             
140
155
164
154
153
160 -9744.24963670
-9744.30001681
-9744.33953891
-9744.36584201
-9744.37925372
-9744.39185493
-9744.39836617

No sé cómo escribirlos en la forma que mencioné anteriormente. Además, dado que el archivo se actualiza constantemente, imagino que la pieza de código se combinará con un ciclo while hasta una condición final (sé cómo hacer esta última parte)

¡Espero haberlo explicado claramente!

Respuesta aceptada:

wow solución:

awk 'v && NR==n{ print $6,v > "result.txt" }/^!/{ v=$5; n=NR+1 }' file
  • <condition1> { <statement> ... }<condition2>{ <statement> ... } – las condiciones con las declaraciones respectivas se evaluarán consecutivamente

  • /^!/{ v=$5; n=NR+1 } – al encontrar la línea que comienza con ! – captura el valor del quinto campo $5 y planifique el siguiente número de línea NR+1 (asignando a la variable n )

  • v && NR==n – si tenemos el primer número crucial v y el número de registro actual NR es el “Número de línea siguiente” necesario n – imprime los valores en el archivo result.txt

El result.txt contenido del archivo:

188 -9744.24963670
140 -9744.30001681
155 -9744.33953891
164 -9744.36584201
154 -9744.37925372
153 -9744.39185493
160 -9744.39836617

Linux
  1. ¿Eliminar eficientemente el primer par de líneas de un archivo de texto?

  2. Contar líneas, palabras y caracteres de un archivo en Linux

  3. Eliminación de líneas específicas de un archivo en la línea de comandos de Linux

  4. Comando wc de linux

  5. Imprimir la última línea de un archivo, desde la CLI

Cómo quitar líneas de un archivo usando el comando Sed

Listado de líneas de un solo archivo en DIFF

¿En qué se diferencia install -c de cp?

Eliminar las primeras N líneas de un archivo de registro activo

Dibujar aleatoriamente un cierto número de líneas de un archivo de datos

¿Cómo mostrar ciertas líneas de un archivo de texto en Linux?