Impression de la dernière colonne d'une ligne dans un fichier

136

J'ai un fichier qui est constamment écrit / mis à jour. Je veux trouver la dernière ligne contenant un mot particulier, puis imprimer la dernière colonne de cette ligne.

Le fichier ressemble à ceci. D'autres lignes A1 / B1 / C1 y seront ajoutées au fil du temps.

A1 123 456
B1 234 567
C1 345 678
A1 098 766
B1 987 6545
C1 876 5434

J'ai essayé d'utiliser

tail -f file | grep A1 | awk '{print $NF}'

pour imprimer la valeur 766, mais rien n'est sorti.

Y a-t-il un moyen de faire cela?

Rayne
la source

Réponses:

201

Vous ne voyez rien, à cause de la mise en mémoire tampon. La sortie est affichée, lorsqu'il y a suffisamment de lignes ou que la fin du fichier est atteinte. tail -fsignifie attendre plus d'entrée, mais il n'y a plus de lignes fileet donc le tuyau vers grepn'est jamais fermé.

Si vous omettez -fde tailla sortie s'affiche immédiatement:

tail file | grep A1 | awk '{print $NF}'

@EdMorton a raison, bien sûr. Awk peut également rechercher A1, ce qui raccourcit la ligne de commande à

tail file | awk '/A1/ {print $NF}'

ou sans queue, montrant la dernière colonne de toutes les lignes contenant A1

awk '/A1/ {print $NF}' file

Merci au commentaire de @ MitchellTracy, tailpeut manquer l'enregistrement contenant A1et ainsi vous n'obtenez aucune sortie du tout. Cela peut être résolu en basculant tailet awk, en cherchant d'abord dans le fichier et en affichant seulement la dernière ligne:

awk '/A1/ {print $NF}' file | tail -n1
Olaf Dietsche
la source
15
Vous n'avez jamais besoin de grep + awk car awk peut faire sa propre comparaison RE. "grep A1 | awk '{print $ NF}'" devrait simplement être "awk '/ A1 / {print $ NF}'". De plus, si vous n'utilisez pas tail -f alors vous n'avez pas du tout besoin de tail, vous pouvez simplement faire: awk '/ A1 / {f = $ NF} END {print f}' file
Ed Morton
1
Ce n'est pas tout à fait correct, car la colonne peut ne pas apparaître dans la fenêtre que Raw tailvous donne. À moins que vous ne sachiez qu'il apparaîtra avec une certaine fréquence, il serait plus sûr de le faire awk '/A1/ {print $NF}' file | tail -n1.
Mitchell Tracy
27

Pour imprimer la dernière colonne d'une ligne, utilisez simplement $ (NF):

awk '{print $(NF)}' 
Gennadiy Zolotaryov
la source
12

Une façon en utilisant awk:

tail -f file.txt | awk '/A1/ { print $NF }'
Steve
la source
Je pensais que c'était la bonne solution au problème affiché (+1!) Mais maintenant je vois que je ne comprends pas la question. L'OP veut le dernier champ de la LAST LINE du fichier, mais il n'y a pas de LAST LINE si vous utilisez tail -f. Peut-être qu'il veut dire la dernière ligne ACTUELLEMENT dans le fichier, auquel cas voir l'un de mes autres commentaires.
Ed Morton
Très bon et simple. Pouces vers le haut. Thumbs down for awk's cryptic syntax :)
stamster
11

Vous pouvez le faire sans awk avec juste quelques tuyaux.

tac file | grep -m1 A1 | rev | cut -d' ' -f1 | rev
miono
la source
Cela résout votre problème, mais cela n'utilise pas vraiment awk. J'espère que c'est assez bon pour toi de toute façon.
miono
4

peut-être que cela fonctionne?

grep A1 file | tail -1 | awk '{print $NF}'
hgh
la source
2

Vous pouvez tout faire en awk:

<file awk '$1 ~ /A1/ {m=$NF} END {print m}'
Thor
la source
1
Vous n'avez pas besoin de split () et d'un tableau, il suffit de sauvegarder le dernier champ et de l'imprimer: awk '/ A1 / {f = $ NF} END {print f}' file
Ed Morton
2

Utiliser Perl

$ cat rayne.txt
A1 123 456
B1 234 567
C1 345 678
A1 098 766
B1 987 6545
C1 876 5434


$ perl -lane ' /A1/ and $x=$F[2] ; END { print "$x" } ' rayne.txt
766

$
pile0114106
la source
Ça a l'air trop compliqué, fais-leperl -lane 'print $F[2] if /A1/' rayne.txt
Salut-Angel le
1
@ Salut-Angel..la question demande la dernière occurrence de A1. votre réponse imprimera tous les matchs .. btw si vous aimez ma réponse, pls upvote it
stack0114106
1

awk -F " " '($1=="A1") {print $NF}' FILE | tail -n 1

À utiliser awkavec le séparateur de champ -F défini sur un espace "".

Utilisez le modèle $1=="A1" et l' action {print $NF} , cela imprimera le dernier champ de chaque enregistrement où le premier champ est "A1". Transformez le résultat en queue et utilisez l' -n 1option pour n'afficher que la dernière ligne.

JimBob
la source
0

Exécutez ceci sur le fichier:

awk 'ORS=NR%3?" ":"\n"' filename

et vous obtiendrez ce que vous recherchez.

Aziz
la source
0

Ce n'est pas le problème réel ici, mais cela pourrait aider quelqu'un: je faisais awk "{print $NF}", notez les mauvaises citations. awk '{print $NF}'Cela devrait être le cas , pour que le shell ne se développe pas $NF.

delucasvb
la source
-2

ls -l | awk '{print $9}' | tail -n1

Cristian
la source
1
Comment cela est-il même lié à la question du PO?
Hickory420