Stampa l'ultima colonna di una riga in un file


135

Ho un file che viene costantemente scritto / aggiornato. Voglio trovare l'ultima riga contenente una determinata parola, quindi stampare l'ultima colonna di quella riga.

Il file è simile al seguente. Altre linee A1 / B1 / C1 verranno aggiunte nel tempo.

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

Ho provato ad usare

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

per stampare il valore 766, ma non viene emesso nulla.

C'è un modo per fare questo?

Risposte:


200

Non vedi nulla, a causa del buffering. Viene mostrato l'output, quando ci sono abbastanza righe o viene raggiunta la fine del file. tail -fsignifica attendere più input, ma non ci sono più righe filee quindi il pipe to grepnon viene mai chiuso.

Se si omette -fdal taill'uscita è mostrato subito:

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

@EdMorton ha ragione, ovviamente. Awk può anche cercare A1, il che accorcia la riga di comando

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

o senza coda, mostrando l'ultima colonna di tutte le righe contenenti A1

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

Grazie al commento di @ MitchellTracy, tailpotrebbe mancare il record contenente A1e quindi non si ottiene alcun risultato. Questo può essere risolto cambiando taile awk, cercando prima attraverso il file e solo dopo mostra l'ultima riga:

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

15
Non hai mai bisogno di grep + awk poiché awk può fare il proprio confronto RE. "grep A1 | awk '{print $ NF}'" dovrebbe essere semplicemente "awk '/ A1 / {print $ NF}'". Inoltre, se non stai usando tail -f, allora non hai affatto bisogno di tail, puoi semplicemente fare: awk '/ A1 / {f = $ NF} END {print f}' file
Ed Morton

1
Questo non è del tutto corretto, poiché la colonna potrebbe non apparire nella finestra che tailti dà Raw . A meno che tu non sappia che apparirà con una certa frequenza, sarebbe più sicuro awk '/A1/ {print $NF}' file | tail -n1.
Mitchell Tracy,


12

Un modo usando awk:

tail -f file.txt | awk '/A1/ { print $NF }'

Ho pensato che fosse la soluzione giusta al problema pubblicato (+1!) Ma ora vedo che non capisco la domanda. L'OP vuole l'ultimo campo dall'ULTIMA LINEA del file, ma non c'è ULTIMA LINEA se stai usando tail -f. Forse intende l'ultima riga ATTUALMENTE nel file, nel qual caso vedere uno dei miei altri commenti.
Ed Morton,

Molto buono e semplice. Pollice su. Pollice in giù per awkla sintassi criptica :)
criceto

11

Puoi farlo senza imbrogliare con solo alcune pipe.

tac file | grep -m1 A1 | rev | cut -d' ' -f1 | rev

Questo risolve il tuo problema, ma non usa davvero awk. Spero che sia abbastanza buono per te comunque.
miono,

4

forse funziona?

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

2

Puoi fare tutto in awk:

<file awk '$1 ~ /A1/ {m=$NF} END {print m}'

1
Non hai bisogno di split () e un array, basta salvare l'ultimo campo e stamparlo: awk '/ A1 / {f = $ NF} END {print f}' file
Ed Morton,

2

Utilizzando 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

$

Sembra troppo complicato, bastaperl -lane 'print $F[2] if /A1/' rayne.txt
Ciao-Angel,

1
@ Ciao Angelo ... la domanda chiede l'ultima occorrenza di A1. la tua risposta stamperà tutte le partite .. a proposito se ti piace la mia risposta, ti preghiamo di
votarla

1

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

Utilizzare awkcon il separatore di campo -F impostato su uno spazio "".

Usa il modello $1=="A1" e l' azione {print $NF} , questo stamperà l'ultimo campo in ogni record in cui il primo campo è "A1". Inoltra il risultato in coda e usa l' -n 1opzione per mostrare solo l'ultima riga.


0

Eseguire questo sul file:

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

e otterrai quello che stai cercando.


0

Non è il vero problema qui, ma potrebbe aiutare qualcuno: stavo facendo awk "{print $NF}", notare le virgolette sbagliate. Dovrebbe essere awk '{print $NF}', in modo che la shell non si espanda $NF.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.