Трубопровод от grep до awk не работает

34

Я пытаюсь grepв текущем tailфайле журнала и получить nслово из строки. Пример файла:

$ 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

Теперь, если я сделаю 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

Если я grepчто tail:

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

Но если я awkчто grep:

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

Ничего, независимо от того, как долго я жду. Я подозреваю, что это как-то связано с тем, как работает поток.

У кого-нибудь есть подсказка?

Бельмин Фернандес
источник

Ответы:

56

Это, вероятно, буферизация вывода из grep. Вы можете отключить это с grep --line-buffered.

Но вам не нужно передавать данные из grep в awk. awk может сам сопоставить шаблон регулярного выражения.

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

саз
источник
8

Использование tail -f test.txt | awk '/Beam/{print $3}'работает для меня. А также с помощью tail -f test.txt | grep --line-buffered Beam | awk '{print $3}'(GNU grep).

Проблема здесь в том, если awkданные получены построчно или в виде одного большего блока данных. GNU-версия grep отправляет вывод в больших блоках, поскольку он более эффективен, но awkдолжен построчно читать, чтобы выводить построчно.

Поместите это так: grepбудет отправлять данные только тогда, когда буфер заполнен, awk ожидает, что этот буфер будет заполнен, поэтому он ничего не отправляет.

Arcege
источник
4

Смотрите --line-bufferedвариант grep.

choroba
источник