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íneaNR+1
(asignando a la variablen
) -
v && NR==n
– si tenemos el primer número crucialv
y el número de registro actualNR
es el “Número de línea siguiente” necesarion
– imprime los valores en el archivoresult.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