Je me demandais s'il existe un moyen simple d'utiliser awk ou toute autre commande pour analyser un fichier texte tel qu'un fichier de quelque chose comme:
Step Temp Enthalpy
0 0 -368
100 1 -369
200 2 -372
300 6 -362
400 9 -365
SHAKE stats (type/ave/delta) on step 500
1 1.09 8.71362e-08
500 13 -358
600 15 -339
.
.
900 25 -306
SHAKE stats (type/ave/delta) on step 1000
1 1.09 7.06858e-08
1000 28 -306
.
.
.
pourrait imprimer une sortie de la colonne spécifique de nombres que je veux, comme uniquement les valeurs de température. Je sais que je pourrais faire quelque chose comme awk '{print $2}'
pour les valeurs de température, mais mon fichier de données particulier contient d'autres lignes de données différentes avant et après le tableau 'Step Temp Enthalpy', ce qui le rend peu pratique. J'aimerais donc couper idéalement. avant et après cette information 'Step Temp Enthalpy' et imprimez uniquement la colonne de cette section du fichier de données dont j'ai besoin. Le fichier de données contient également cette ligne "SHAKE stats" toutes les 5 étapes, en plus d'une ligne après le "1 1.09 ... etc", que j'aimerais supprimer. Si je devais imprimer uniquement la colonne de température, j'aimerais qu'elle soit imprimée:
0
1
2
6
9
13
15
.
.
25
28
Le modèle simple que vous avez est de supprimer la colonne 2 dans les lignes contenant/en commençant par les chiffres. La structure habituelle des commandes awk
est /Pattern in current line/ { commands};
. Les commandes entre accolades ne sont exécutées que si un motif est trouvé dans la ligne en cours. Nous pouvons donc faire:
$ awk '/^[[:digit:]]/{print $2}' input.txt
0
1
2
6
9
1.09
13
15
25
1.09
28
Pour supprimer également les nombres à virgule flottante, ajoutez un motif supplémentaire avec l'opérateur AND logique &&
:
$ awk '/^[[:digit:]]/ && $0 !~ /[.]/ {print $2}' input.txt
0
1
2
6
9
13
15
25
28
Vous pouvez également utiliser un modèle de négation pour exclure les statistiques de secousse:
awk '!/^SHAKE/ && $0 !~ /[.]/ {print $2}' input.txt
Pour répondre à la question dans le commentaire, vous pouvez combiner un motif d'intervalle (quelque chose comme /Pattern1/,/Pattern2/ {commands}
) avec l'instruction if. Le modèle de plage exécute des commandes entre accolades uniquement pour les lignes correspondant à la plage, puis l'instruction if peut effectuer un filtrage supplémentaire. Dans ce cas particulier, vous pouvez simplement le combiner avec la solution précédente comme ceci:
$ awk '$0 == "Step Temp Enthalpy",0 { if( $0 ~ /^[[:digit:]]/ && $0 !~ /[.]/ ) print $2 }' input.txt
Le modèle $0 == "Step Temp Enthalpy",0
signifie le traitement de la ligne exacte Step Temp Enthalpy
à 0
, c'est-à-dire à la fin du fichier.
Voici une approche (éventuellement) plus simple basée sur la structure des données plutôt que sur la correspondance du contenu:
SHAKE stats
getline
et passez à la suiteAlors
$ awk '!(NR%7) {getline; next} {print $2}' data
Temp
0
1
2
6
9
13
15
25
28