Как "grep" непрерывный поток?
Можно ли использовать grep
для непрерывного потока?
Я имею в виду некоторую команду tail -f <file>
, но с grep
на выходе, чтобы сохранить только интересующие меня строки.
Я пробовал tail -f <file> | grep pattern
, но кажется, что grep
может выполняться только один раз tail
заканчивается, то есть никогда.
Ответы
Ответ 1
Включите режим буферизации строки grep
при использовании BSD grep (FreeBSD, Mac OS X и т.д.)
tail -f file | grep --line-buffered my_pattern
Вам не нужно делать это для GNU grep (используется практически во всех Linux), поскольку он будет сбрасываться по умолчанию (YMMV для других Unix-подобных приложений, таких как SmartOS, AIX или QNX).
Ответ 2
Я использую tail -f <file> | grep <pattern>
все время.
Он будет ждать, пока grep не начнет сбрасываться, пока он не закончится (я использую Ubuntu).
Ответ 3
Я думаю, что ваша проблема в том, что grep использует некоторую буферизацию вывода. Попробуйте
tail -f file | stdbuf -o0 grep my_pattern
он установит режим буферизации вывода grep небуферизованным.
Ответ 4
В большинстве случаев вы можете tail -f /var/log/some.log |grep foo
, и он будет работать нормально.
Если вам нужно использовать несколько grep в работающем файле журнала, и вы обнаружите, что у вас нет выхода, вам может понадобиться вставить переключатель --line-buffered
в grep (s) средний, например так:
tail -f /var/log/some.log | grep --line-buffered foo | grep bar
Ответ 5
Если вы хотите найти совпадения во всем файле (а не только в хвосте), и вы хотите, чтобы он сидел и ждал новых совпадений, это прекрасно работает:
tail -c +0 -f <file> | grep --line-buffered <pattern>
Флаг -c +0
указывает, что выход должен начинаться с 0
bytes (-c
) с начала (+
) файла.
Ответ 6
Не видел, чтобы кто-нибудь предложил мое обычное решение для этого:
less +F <file>
ctrl + c
/<search term>
<enter>
shift + f
Я предпочитаю это, потому что вы можете использовать ctrl + c
для остановки и навигации по файлу в любое время, а затем просто нажать shift + f
чтобы вернуться к поиску в реальном времени.
Ответ 7
Вы можете рассматривать этот ответ как улучшение. Обычно я использую
tail -F <fileName> | grep --line-buffered <pattern> -A 3 -B 5
-F лучше в случае поворота файла (-F не будет работать должным образом, если файл повернут)
-A и -B полезны для получения линий непосредственно до и после появления шаблона. Эти блоки будут появляться между разделителями пунктирных линий
Но я предпочитаю делать следующее
tail -F <file> | less
это очень полезно, если вы хотите искать внутри потоковых журналов. Я имею в виду, иди назад и вперед и посмотри глубоко
Ответ 8
sed будет лучшим выбором (редактор потоков)
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.
Ответ 9
Да, на самом деле все будет хорошо. Grep
, и большинство команд Unix работают по потокам по одной строке за раз. Каждая строка, которая выходит из хвоста, будет анализироваться и передаваться, если она соответствует.
Ответ 10
Эта команда работает для меня (Suse):
mail-srv:/var/log # tail -f /var/log/mail.info |grep --line-buffered LOGIN >> logins_to_mail
сбор логинов к почтовому сервису
Ответ 11
Используйте awk (еще одна полезная утилита bash) вместо grep, где у вас нет опции для буферизации строк! Он будет непрерывно передавать ваши данные из хвоста.
вот как вы используете grep
tail -f <file> | grep pattern
Вот как вы будете использовать awk
tail -f <file> | awk '/pattern/{print $0}'