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?

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

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


12

W jedną stronę za pomocą awk:

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

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

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}'

2

Możesz to wszystko zrobić w awk:

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

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

$

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ę.


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.


0

Wykonaj to na pliku:

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

a dostaniesz to, czego szukasz.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.