Drukowanie ostatniej kolumny wiersza w pliku

149

Mam plik, który jest stale zapisywany / aktualizowany. Chcę znaleźć ostatnią linię zawierającą określone słowo, a następnie wydrukować ostatnią kolumnę tego wiersza.

Plik wygląda mniej więcej tak. Z czasem zostanie do niego dołączonych więcej linii A1 / B1 / C1.

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

Próbowałem użyć

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

wydrukować wartość 766, ale nic nie jest wyświetlane.

Czy jest na to sposób?

Rayne
źródło

Odpowiedzi:

217

Nic nie widzisz z powodu buforowania. Dane wyjściowe są wyświetlane, gdy jest wystarczająco dużo wierszy lub zostanie osiągnięty koniec pliku. tail -foznacza czekanie na więcej danych wejściowych, ale nie ma więcej linii, filewięc potok do grepnigdy nie jest zamknięty.

Jeśli pominąć -fod tailwyjścia jest pokazany natychmiast:

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

@EdMorton ma oczywiście rację. Awk może również wyszukiwać A1, co skraca wiersz poleceń do

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

lub bez ogona, pokazując ostatnią kolumnę wszystkich wierszy zawierających A1

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

Dzięki komentarzowi @ MitchellTracy możesz tailprzegapić rekord zawierający, A1a tym samym nie otrzymasz żadnego wyniku. Można to rozwiązać, przełączając się taili awkprzeszukując najpierw plik, a dopiero potem pokazując ostatnią linię:

awk '/A1/ {print $NF}' file | tail -n1
Olaf Dietsche
źródło
15
Nigdy nie potrzebujesz grep + awk, ponieważ awk może wykonać własne porównanie RE. "grep A1 | awk '{print $ NF}'" powinno być po prostu "awk '/ A1 / {print $ NF}'". Ponadto, jeśli nie używasz tail -f, to w ogóle nie potrzebujesz tail, możesz po prostu zrobić: awk '/ A1 / {f = $ NF} END {print f}' file
Ed Morton
1
To nie jest do końca w porządku, ponieważ kolumna może nie pojawić się w oknie, które taildaje ci raw . O ile nie wiesz, że będzie się to pojawiało z określoną częstotliwością, byłoby to bezpieczniejsze awk '/A1/ {print $NF}' file | tail -n1.
Mitchell Tracy
29

Aby wydrukować ostatnią kolumnę wiersza, użyj $ (NF):

awk '{print $(NF)}' 
Gennadiy Zolotaryov
źródło
12

W jedną stronę za pomocą awk:

tail -f file.txt | awk '/A1/ { print $NF }'
Steve
źródło
Myślałem, że to dobre rozwiązanie zamieszczonego problemu (+1!), Ale teraz widzę, że nie rozumiem pytania. OP chce ostatniego pola z OSTATNIEJ LINII pliku, ale nie ma OSTATNIEJ LINII, jeśli używasz tail -f. Może ma na myśli ostatnią linię OBECNIE w pliku, w takim przypadku zobacz jeden z moich innych komentarzy.
Ed Morton
Bardzo dobre i proste. Kciuki w górę. Kciuki w dół za awktajemniczą składnię :)
stamster
11

Możesz to zrobić bez awk, używając tylko kilku potoków.

tac file | grep -m1 A1 | rev | cut -d' ' -f1 | rev
miono
źródło
To rozwiązuje problem, ale tak naprawdę nie używa awk. Mam nadzieję, że i tak jest dla ciebie wystarczająco dobre.
miono
4

może to działa?

grep A1 file | tail -1 | awk '{print $NF}'
hgh
źródło
2

Możesz to wszystko zrobić w awk:

<file awk '$1 ~ /A1/ {m=$NF} END {print m}'
Thor
źródło
1
Nie potrzebujesz split () i tablicy, po prostu zapisz ostatnie pole i wydrukuj to: awk '/ A1 / {f = $ NF} END {print f}' file
Ed Morton
2

Korzystanie z Perla

$ 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

$
stack0114106
źródło
Wygląda na zbyt skomplikowane, po prostu zróbperl -lane 'print $F[2] if /A1/' rayne.txt
Hi-Angel
1
@ Cześć-Aniele… pytanie dotyczy ostatniego wystąpienia A1. Twoja odpowiedź spowoduje wypisanie wszystkich dopasowań. Przy okazji, jeśli podoba ci się moja odpowiedź, proszę o jej
głosowanie
1

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

Należy używać awkz separatorem pól -F ustawionym na spację „”.

Użyj wzorca $1=="A1" i akcji. {print $NF} Spowoduje to wydrukowanie ostatniego pola w każdym rekordzie, w którym pierwsze pole to „A1”. Przełóż wynik do końca i użyj -n 1opcji, aby pokazać tylko ostatnią linię.

JimBob
źródło
1

Nie jest to rzeczywisty problem, ale może komuś pomóc: robiłem awk "{print $NF}", zanotuj niewłaściwe cytaty. Powinien być awk '{print $NF}', aby powłoka się nie rozszerzyła $NF.

delucasvb
źródło
0

Wykonaj to na pliku:

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

a dostaniesz to, czego szukasz.

Aziz
źródło
-3

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

Cristian
źródło
1
Jak to się ma w ogóle do pytania PO?
Hickory420