Jai ce script awk
qui prend le fichier dentrée suivant, input.txt
et produit la sortie ci-dessous. Quelquun peut-il prendre le temps dexpliquer comment ce script awk
fonctionne? Jai passé un peu de temps dessus et cela na pas beaucoup de sens.
Entrée:
$ cat input.txt
FINISHED RSYNCJOBNA 20140502 0021 2182096 2082096 6 5 2014820905820902 10:02:15 2014820905820902 10:56:42 0:54:27 INITIATED RSYNCJOBNA 20140502 0022 3282096 3182096 6 5 2014820905820902 15:31:06 0:06:04 ce eque**
Résultat:
RSYNCJOBNA|0021|20140502|10:02:15|10:56:42|0:54:27|FINISHED RSYNCJOBNA|0022|20140502|15:31:06| |0:06:04|INITIATED
Commande pour obtenir la sortie ci-dessus:
awk -v OFS="|" "/FINISHED|INITIATED/ { status = $1; getline; jobname = $1; getline; sequence = $2; date = $1; getline; start = $2; getline; if (status == "FINISHED") { end = $2; getline } else { end = " " } runtime = $1; print jobname, sequence, date, start, end, runtime, status; }" input.txt
Je crois comprendre que /FINISHED|INITIATED/ {}
signifie que les commandes entre accolades ne seront exécutées que sur les lignes correspondant à FINISHED
ou INITIATED
mais autant que je sache daprès la sortie, le script semble analyser à partir de toutes lignes. Que se passe-t-il?
Commentaires
Réponse
La fonction getline
lit la ligne suivante et y déplace le script. Ainsi, Les appels getline
consécutifs passent à la ligne suivante. Ceci est peut-être plus facile à comprendre avec un exemple:
$ cat input.txt foo 1 2 $ awk "/foo/{print; getline; print; getline; print}" input.txt foo 1 2
Comme vous pouvez voir ci-dessus, le script traitera la première ligne car elle correspond à foo
. Chaque appel à getline
lira la ligne après la ligne actuelle, de sorte que les appels print
suivants impriment les lignes suivantes.
Réponse
Si vous ne savez pas ce quune fonction awk
fait, alors la stratégie habituelle est pour jeter un œil à la page de manuel:
getline
Définit $ 0 à partir de lenregistrement dentrée suivant; définit NF, NR, FNR, RT
Le bloc de commande nest en effet exécuté que deux fois. Les autres lignes sont gérées via getline
depuis le block.
Cela pourrait être réécrit en:
/FINISHED|INITIATED/ { status = $1; line_number=0; next; } { line_number++; } line_number==1 { jobname = $1; } line_number==2 { sequence = $2; date = $1; } ...
Commentaires
- Que se passe-t-il si lenregistrement suivant est vide?
- @AvinashRaj Ni votre code ni mon alternative ne regarde le contenu des lignes (à lexception de
/FINISHED|INITIATED/
). Les lignes sont juste décomptées. Les données doivent être disposées exactement (à partir dun awk parsi ng perspective) comme vous lavez montré, sinon le code se cassera.
/FINISHED|INITIATED/
, awk recherche la ligne correspondante et ne fait lopération que sur cette ligne particulière. Mais lopération a été effectuée sur toutes les lignes. Comment?