8

Как использовать 'grep' для непрерывного потока?

9

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

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

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

5 ответ(ов)

15

Чтобы включить режим построчной буферизации в grep на BSD (таких как FreeBSD, Mac OS X и др.), вы можете использовать следующую команду:

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

Ранее для GNU grep (который используется практически на всех дистрибутивах Linux) параметр --line-buffered, как правило, не имел значения, так как по умолчанию происходило принудительное сбрасывание буфера. Однако с ноября 2020 года этот параметр стал необходимым (как минимум, для GNU grep 3.5 на openSUSE) и, судя по комментариям, это также верно и для других систем.

Обратите внимание, что поведение может отличаться в зависимости от конкретного дистрибутива и версии grep, поэтому если вы работаете в среде, отличной от Linux, возможно, стоит проверять документацию для вашей ОС, чтобы всегда быть в курсе изменений и возможностей инструмента.

1

Вы можете использовать команду tail -f <file> | grep --line-buffered <pattern>, чтобы избежать проблемы с буферизацией. По умолчанию grep вызывает буферизацию вывода, что может привести к задержкам в отображении результатов. Используя параметр --line-buffered, вы можете получить результаты сразу же по мере их появления, а не дожидаться завершения вывода. Сначала выполните команду:

tail -f <file> | grep --line-buffered <pattern>

Это должно решить вашу проблему, и вы получите вывод в реальном времени без задержек.

0

Если вам нужно находить совпадения во всем файле (а не только в его конце) и ожидать появления новых совпадений, вы можете использовать следующую команду:

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

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

0

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

tail -f file | stdbuf -o0 grep my_pattern

Это установит режим буферизации вывода для grep на неблокирующий.

0

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

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

tail -f /var/log/some.log | grep --line-buffered foo | grep bar
Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь