Sto cercando di estrarre alcuni dati da un file che si aggiorna costantemente e ho capito come filtrare due stringhe con grep. L'output è il seguente:
! 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
Ora quello che vorrei fare è estrarre da queste righe i numeri come segue:
dalla riga che inizia con ! Voglio il numero nella colonna n. 5 e dalla riga successiva nell'output di grep voglio il numero nella colonna n. 6.
Successivamente vorrei che questi numeri fossero scritti in un file separato come due colonne separate come:
188 -9744.24963670
140 -9744.30001681
155 -9744.33953891
164 -9744.36584201
Stavo pensando che un approccio con awk scorrendo tutti questi risultati grep e poi guardando le righe dispari e stampando la colonna 5 e poi per le righe pari stampando la colonna 6. Ma non ho idea di come farlo.
Ho provato a estrarre i singoli risultati in variabili separatamente:
var1=$(grep '!' input.file | awk '{print $5}')
e
var2=$(grep 'convergence has been achieved' input.file | awk '{print $6}')
e poi ho provato a scriverli in un file come:
echo $var1 $var2 > data.dat
Tuttavia il risultato non è quello previsto:
188
140
155
164
154
153
160 -9744.24963670
-9744.30001681
-9744.33953891
-9744.36584201
-9744.37925372
-9744.39185493
-9744.39836617
Non so come scriverli nella forma che ho menzionato sopra. Inoltre siccome il file è costantemente aggiornato immagino il pezzo di codice da combinare con un ciclo while e end condition (so come fare quest'ultima parte)
Spero di averlo spiegato chiaramente!
Risposta accettata:
Awk soluzione:
awk 'v && NR==n{ print $6,v > "result.txt" }/^!/{ v=$5; n=NR+1 }' file
-
<condition1> { <statement> ... }<condition2>{ <statement> ... }
– le condizioni con le rispettive dichiarazioni verranno valutate consecutivamente -
/^!/{ v=$5; n=NR+1 }
– all'incontro con la riga che inizia con!
– cattura il valore del 5° campo$5
e pianifica il numero di riga successivoNR+1
(assegnando alla variabilen
) -
v && NR==n
– se abbiamo il 1° numero crucialev
e il numero di registrazione correnteNR
è il "numero di riga successivo" necessarion
– stampa i valori nel fileresult.txt
Il result.txt
contenuto del file:
188 -9744.24963670
140 -9744.30001681
155 -9744.33953891
164 -9744.36584201
154 -9744.37925372
153 -9744.39185493
160 -9744.39836617