GNU/Linux >> Tutoriels Linux >  >> Linux

Awk de différentes lignes ?

J'essaie d'extraire des données d'un fichier qui est constamment mis à jour et j'ai compris comment filtrer deux chaînes avec grep. Le résultat est le suivant :

!    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

Maintenant, ce que je voudrais faire, c'est extraire de ces lignes les nombres comme suit :
de la ligne commençant par ! Je veux le nombre dans la colonne n° 5 et à partir de la ligne suivante dans la sortie grep, je veux le nombre dans la colonne n° 6.
Ensuite, je voudrais que ces nombres soient écrits dans un fichier séparé sous forme de deux colonnes séparées comme :

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

Je pensais qu'une approche avec awk en parcourant tous ces résultats de grep, puis en regardant les lignes impaires et la colonne d'impression 5, puis pour les lignes paires, imprime la colonne 6. Mais je n'ai aucune idée de comment faire cela.

J'ai essayé d'extraire les résultats individuels dans des variables séparément :

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

et

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

puis j'ai essayé de les écrire dans un fichier comme :

echo $var1 $var2 > data.dat

Cependant le résultat n'est pas celui attendu :

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

Je ne sais pas comment les écrire sous la forme que j'ai mentionnée ci-dessus. De plus, comme le fichier est constamment mis à jour, j'imagine que le morceau de code doit être combiné avec une boucle while jusqu'à et une condition de fin (je sais comment faire cette dernière partie)

J'espère que j'ai expliqué cela clairement !

Réponse acceptée :

mal à l'aise solution :

awk 'v && NR==n{ print $6,v > "result.txt" }/^!/{ v=$5; n=NR+1 }' file
  • <condition1> { <statement> ... }<condition2>{ <statement> ... } – les conditions avec les déclarations respectives seront évaluées consécutivement

  • /^!/{ v=$5; n=NR+1 } – en rencontrant une ligne commençant par ! – saisir la valeur du 5ème champ $5 et prévoir le numéro de ligne suivant NR+1 (affectant à la variable n )

  • v && NR==n – si on a le 1er nombre crucial v et le numéro d'enregistrement courant NR est le "numéro de la ligne suivante" nécessaire n – imprimer les valeurs dans le fichier result.txt

Le result.txt contenu du fichier :

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

Linux
  1. Lecture de lignes à partir d'un fichier avec Bash :pour Vs. Tandis que?

  2. Suppression de lignes spécifiques d'un fichier dans la ligne de commande Linux

  3. Commande wc Linux

  4. Supprimer les N premières lignes d'un fichier journal actif

  5. en quoi cp -f est-il différent de cp --remove-destination ?

Comment supprimer des lignes d'un fichier à l'aide de la commande Sed

Imprimer la dernière ligne d'un fichier, à partir de la CLI

Supprimer les lignes paires ou impaires d'un fichier texte

Liste des lignes d'un seul fichier dans DIFF

En quoi install -c est différent de cp

Tirer au hasard un certain nombre de lignes d'un fichier de données