I am trying to extract some data from a file that is constantly updating and I have figured out how to filter two strings with grep. The output is as follows:
! 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
Now what I would like to do is to extract from these lines the numbers as follows:
from the line starting with ! I want the number in column no 5 and from the next line in the grep output I want the number in column no 6.
Next I would like these numbers written in a separate file as two separated columns as:
188 -9744.24963670
140 -9744.30001681
155 -9744.33953891
164 -9744.36584201
I was thinking that an approach with awk by looping through all these grep results and then looking at odd numbered lines and print column 5 and then for even lines print column 6. But I have no idea how to do this.
I have tried extracting individual results into variables separately:
var1=$(grep '!' input.file | awk '{print $5}')
and
var2=$(grep 'convergence has been achieved' input.file | awk '{print $6}')
and then I tried to write them to a file as:
echo $var1 $var2 > data.dat
However the result is not as expected:
188
140
155
164
154
153
160 -9744.24963670
-9744.30001681
-9744.33953891
-9744.36584201
-9744.37925372
-9744.39185493
-9744.39836617
I don't know how to write them in the form I mentioned above. Also since the file is constantly updated I imagine the piece of code to be combined with a while loop until and end condition (I know how to do this last part)
I hope I explained this clearly!
Best Answer
awk solution:
<condition1> { <statement> ... }<condition2>{ <statement> ... }
- conditions with respective statements will be evaluated consecutively/^!/{ v=$5; n=NR+1 }
- on encountering line starting with!
- capture the 5th field value$5
and plan the next line numberNR+1
(assigning to variablen
)v && NR==n
- if we have the 1st crucial numberv
and the current record numberNR
is the needed "next line number"n
- print the values into fileresult.txt
The
result.txt
file contents: