Возможно ли использовать grep
непрерывный поток?
Я имею в виду что-то вроде tail -f <file>
команды, но с grep
выводом, чтобы сохранить только те строки, которые меня интересуют.
Я пытался, tail -f <file> | grep pattern
но кажется, что grep
может быть выполнено только после tail
окончания, то есть никогда.
tail -f file
работает (я вижу новый вывод в режиме реального времени)Ответы:
Включите
grep
режим буферизации строки при использовании BSD grep (FreeBSD, Mac OS X и т. Д.)Вам не нужно делать это для GNU grep (используется практически во всех Linux), поскольку он будет сбрасываться по умолчанию (YMMV для других Unix-подобных приложений, таких как SmartOS, AIX или QNX).
источник
strace
. Без--line-buffered
этого не получится.tail -f | grep
, и я--line-buffered
ее решаю (в Ubuntu 14.04, GNU grep version 2.16). Где реализована логика использования строки, если stdout является tty? В git.savannah.gnu.org/cgit/grep.git/tree/src/grep.c ,line_buffered
устанавливается только с помощью аргумента синтаксического анализа.--line-buffered
я не получаю вывод. Однако после тестирования похоже, что GNU grep делает то, что вы описываете. Так что, как и большинство вещей Unix, это зависит от реализации вашей платформы. Поскольку в вопросе не указана платформа, ваша информация представляется ложной - после просмотра кода для BSD grep и сравнения его с GNU grep, поведение определенно контролируется опцией --line-buffered. Просто GNU grep сбрасывает по умолчанию.Я использую
tail -f <file> | grep <pattern>
все время.Он будет ждать до сброса grep, а не до его завершения (я использую Ubuntu).
источник
Я думаю, что ваша проблема в том, что grep использует некоторую буферизацию вывода. Пытаться
он установит режим буферизации вывода grep в unbuffered.
источник
grep
.unbuffer
(вexpect-dev
пакете на debian) это king . Поэтому я бы использовал unbuffer поверх stdbuf.top
с stdbuf и unbuffer) И на самом деле не существует «волшебного» решения: иногда небуферы тоже терпят неудачу, например, awk использует другую реализацию буфера (stdbuf тоже не будет работать).stdbuf
буферизации `unbuffer и stdio 'на pixelbeat.org/programming/stdio_bufferingЕсли вы хотите найти совпадения во всем файле (а не только в хвосте) и хотите, чтобы он сидел и ждал новых совпадений, это прекрасно работает:
-c +0
Флаг говорит о том , что выход должен начинаться0
байт (-c
) с самого начала (+
) файла.источник
В большинстве случаев вы можете
tail -f /var/log/some.log |grep foo
и это будет работать просто отлично.Если вам нужно использовать несколько greps в работающем файле журнала, и вы обнаружите, что ничего не выводите, вам может понадобиться вставить
--line-buffered
коммутатор в ваш средний grep, например, так:источник
вы можете рассматривать этот ответ как улучшение .. обычно я использую
-F лучше в случае поворота файла (-f не будет работать правильно, если файл повернут)
-A и -B полезны для получения линий непосредственно до и после появления шаблона. Эти блоки будут появляться между разделителями пунктирных линий
Но для меня я предпочитаю делать следующее
это очень полезно, если вы хотите искать внутри потоковых журналов. Я имею в виду, иди назад и вперед и посмотри
источник
grep -C 3 <pattern>
, заменяет -A <N> и -B <N>, если N одинаково.Не видел, чтобы кто-нибудь предложил мое обычное решение для этого:
Я предпочитаю это, потому что вы можете использовать
ctrl + c
для остановки и навигации по файлу в любое время, а затем просто нажать,shift + f
чтобы вернуться к живому потоковому поиску.источник
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.
источник
$BASHPID+1
), будет вашим, во многих ситуациях ложно, и это ничего не делает для решения проблемы буферизации, о которой, вероятно, пытался спросить OP. В частности, рекомендуяsed
болееgrep
здесь , кажется , как только вопрос (сомнительного) предпочтения. (Вы можете вести себяp;q
с ним,grep -m 1
если именно это вы пытаетесь донести.)--line-buffered
не имеет. Я искренне не понимаю минус 1.Да, это на самом деле будет работать просто отлично.
Grep
и большинство команд Unix работают с потоками по одной строке за раз. Каждая строка, которая выходит из хвоста, будет проанализирована и передана, если она совпадает.источник
grep
это последняя команда в цепочке каналов, она будет действовать так, как вы объясняете. Однако, если он находится посередине, он будет буферизовать около 8 Кбайт за раз.Эта команда работает для меня (Suse):
сбор логинов к почтовому сервису
источник
у вас точно не получится
когда вы используете "colortail" в качестве псевдонима для tail, например. в баш
по псевдониму типа вы можете проверить, выводит ли он что-то вроде tail isan of alias
colortail -n 30
. тогда у тебя есть виновник :)Решение:
удалить псевдоним с
убедитесь, что вы используете 'реальный' хвостовой двоичный файл с помощью этой команды
который должен вывести что-то вроде:
и тогда вы можете запустить свою команду
Удачи.
источник
Используйте awk (еще одна отличная утилита bash) вместо grep, где у вас нет опции буферизации строки! Он будет непрерывно передавать ваши данные из хвоста.
вот как вы используете grep
Вот как бы вы использовали awk
источник
{print $0}
это избыточно, поскольку печать выполняется по умолчанию при выполнении условия.)