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?

Belmin Fernandez
quelle

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

cas
quelle
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.

Arcege
quelle
4

Siehe die --line-bufferedOption von grep.

Choroba
quelle