Piping von grep nach awk funktioniert nicht


34

Ich versuche, grepdas laufende tailDateiprotokoll und das nth Wort von einer Linie zu erhalten. Beispieldatei:

$ 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

Wenn ich nun a tue 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

Wenn ich grepdas tail:

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

Aber wenn ich awkdas grep:

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

Nichts, egal wie lange ich warte. Ich vermute, es hängt damit zusammen, wie der Stream funktioniert.

Hat jemand eine Ahnung?

Antworten:


55

Es ist wahrscheinlich die Ausgabepufferung von grep. das kannst du mit deaktivieren grep --line-buffered.

Aber Sie müssen die Ausgabe von grep nicht in awk umleiten. awk kann den Regexp-Pattern-Matching ganz alleine durchführen.

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


8

Verwenden tail -f test.txt | awk '/Beam/{print $3}'funktioniert bei mir. Sowie mit tail -f test.txt | grep --line-buffered Beam | awk '{print $3}'(gnu grep).

Das Problem hierbei ist, ob awkdie Daten zeilenweise oder als ein größerer Datenblock empfangen werden. Die GNU-Version von grep sendet die Ausgabe in größeren Blöcken, da sie effizienter ist, sie awkmuss jedoch zeilenweise gelesen werden, um zeilenweise auszugeben.

Um es so auszudrücken: grepSendet nur Daten, wenn der Puffer voll ist, awk wartet darauf, dass dieser Puffer voll ist, und sendet daher nichts aus.


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.