Как «grep» непрерывный поток? - PullRequest
651 голосов
/ 23 августа 2011

Можно ли использовать grep в непрерывном потоке?

Я имею в виду что-то вроде команды tail -f <file>, но с grep на выходе, чтобы сохранить только те строки, которыеМеня интересует.

Я пробовал tail -f <file> | grep pattern, но кажется, что grep может быть выполнено только после завершения tail, то есть никогда.

Ответы [ 11 ]

1214 голосов
/ 23 августа 2011

Включение режима буферизации строки grep при использовании BSD grep (FreeBSD, Mac OS X и т. Д.)

tail -f file | grep --line-buffered my_pattern

Вам не нужно делать это для GNU grep (используется практически во всех Linux), поскольку он будет сбрасываться по умолчанию (YMMV для других Unix-подобных приложений, таких как SmartOS, AIX или QNX).

113 голосов
/ 23 августа 2011

Я использую tail -f <file> | grep <pattern> все время.

Он будет ждать, пока сбросит grep, а не до его завершения (я использую Ubuntu).

56 голосов
/ 23 августа 2011

Я думаю, что ваша проблема в том, что grep использует некоторую буферизацию вывода.Попробуйте

tail -f file | stdbuf -o0 grep my_pattern

, чтобы установить режим буферизации вывода grep в небуферизованный.

10 голосов
/ 04 мая 2016

В большинстве случаев вы можете tail -f /var/log/some.log |grep foo, и все будет работать нормально.

Если вам нужно использовать несколько greps для работающего файла журнала, и вы обнаружите, что ничего не выводите, возможно, вам потребуетсявставьте --line-buffered переключатель в ваш средний grep (s), например:

tail -f /var/log/some.log | grep --line-buffered foo | grep bar
9 голосов
/ 12 сентября 2017

Если вы хотите найти совпадения во всем файле (а не только в хвосте) и хотите, чтобы он сидел и ждал новых совпадений, это прекрасно работает:

tail -c +0 -f <file> | grep --line-buffered <pattern>

Флаг -c +0 говорит о том, что вывод должен начинаться 0 байтов (-c) с начала (+) файла.

5 голосов
/ 10 апреля 2018

Не видел, чтобы кто-нибудь предлагал мое обычное решение для этого:

less +F <file>
ctrl + c
/<search term>
<enter>
shift + f

Я предпочитаю это, потому что вы можете использовать ctrl + c для остановки и навигации по файлу в любое время, а затем просто нажмитеshift + f для возврата к поиску в потоковом режиме.

3 голосов
/ 21 апреля 2017

sed будет лучшим выбором ( stream editor)

tail -n0 -f <file> | sed -n '/search string/p'

и затем, если вы хотите, чтобы команда tail завершала работу после того, как вы нашли конкретную строку:

tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'

Очевидно, что bashism: $ BASHPID будет идентификатором процесса команды tail. Команда sed будет следующей после tail в конвейере, поэтому идентификатор процесса sed будет $ BASHPID + 1.

2 голосов
/ 28 июля 2016

вы можете рассматривать этот ответ как улучшение .. обычно я использую

tail -F <fileName> | grep --line-buffered  <pattern> -A 3 -B 5

-F лучше при повороте файла (-f не будет работать правильно, если файл повернут)

-A и -B полезны для получения строк непосредственно до и после появления шаблона. Эти блоки будут появляться между разделителями пунктирных линий

Но для себя я предпочитаю делать следующее

tail -F <file> | less

это очень полезно, если вы хотите искать внутри потоковых журналов

1 голос
/ 31 октября 2018

Эта команда работает для меня (Suse):

mail-srv:/var/log # tail -f /var/log/mail.info |grep --line-buffered LOGIN  >> logins_to_mail

сбор логинов на почтовый сервис

0 голосов
/ 22 июня 2014

Используйте awk (еще одну замечательную утилиту bash) вместо grep, где у вас нет опции буферизации строки! Он будет непрерывно передавать ваши данные из хвоста.

вот как вы используете grep

tail -f <file> | grep pattern

Вот как бы вы использовали awk

tail -f <file> | awk '/pattern/{print $0}'
...