Rurowanie z grep do awk nie działa


34

Próbuję przejść grepdo tailpliku dziennika i uzyskać nth słowo z linii. Przykładowy plik:

$ cat > test.txt <<EOL
Beam goes blah
John goes hey
Beam goes what?
John goes forget it
Beam goes okay
Beam goes bye
EOL
^C

Teraz, jeśli zrobię tail:

$ tail -f test.txt
Beam goes blah
John goes hey
Beam goes what?
John goes forget it
Beam goes okay
Beam goes bye
^C

Jeśli grepto tail:

$ tail -f test.txt | grep Beam
Beam goes blah
Beam goes what?
Beam goes okay
Beam goes bye
^C

Ale jeśli awkto grep:

$ tail -f test.txt | grep Beam | awk '{print $3}'

Nic, nie ważne jak długo czekam. Podejrzewam, że ma to związek ze sposobem działania strumienia.

Czy ktoś ma jakieś wskazówki?

Odpowiedzi:


55

Prawdopodobnie buforuje wyjście z grep. możesz to wyłączyć za pomocą grep --line-buffered.

Ale nie musisz przesyłać danych wyjściowych z grep do awk. awk może sam wykonać dopasowanie wyrażenia regularnego.

tail -f test.txt | awk '/Beam/ {print $3}'


8

Używanie tail -f test.txt | awk '/Beam/{print $3}'działa dla mnie. Oprócz używania tail -f test.txt | grep --line-buffered Beam | awk '{print $3}'(gnu grep).

Problem polega na tym, czy awkdane były odbierane wiersz po wierszu, czy jako jeden większy blok danych. Wersja grep GNU wysyła dane wyjściowe w większych blokach, ponieważ jest bardziej wydajna, ale awkmusi czytać wiersz po wierszu, aby wysyłać wiersz po wierszu.

Mówiąc inaczej: grepwyśle ​​dane tylko, gdy bufor jest wypełniony, awk czeka na wypełnienie bufora, więc nic nie wysyła.


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.