Назад | Перейти на главную страницу

Как применить фильтр к выводу в реальном времени `tail -f`?

tail -f path

Вышеупомянутое будет выводить изменения в файл мгновенно, но я хочу применить фильтр к выходу, показывать только при наличии ключевого слова xxx в этом.

Как к этому подойти?

В Unix вы можете передать вывод одной программы в другую.

Итак, чтобы отфильтровать хвост, вы можете использовать grep:

tail -f path | grep your-search-filter

Короткий ответ: tail -f somefile | grep somepattern

Однако, как правило, этого не происходит. Допустим, вы отслеживаете файл, который часто вращается (если это журнал отладки, он может быть повернут несколько раз). В таком случае tail -F твой друг. Я позволю вам найти разницу.

Но tail -f и tail -F сначала распечатайте кучу строк, что часто нежелательно в этом случае использования, поэтому в этом случае добавьте -n0

tail -F -n0 somefile | grep somepattern

Это будет нормально, пока вы не захотите выполнить другую фильтрацию, а затем вам нужно остерегаться буферизации. stdout по умолчанию буферизуется по строкам при записи в терминал но при полной буферизации при записи в канал. Таким образом, следующее будет выдавать строки, как только они будут найдены, потому что tail явно буферизируется по строке (или сбрасывает свой вывод в конце каждой строки), и grep также буферизуется по строке, потому что его вывод идет на ваш терминал:

tail -F -n0 somefile | grep somepattern

Но затем вы решаете использовать что-то вроде awk или cut для дальнейшей обработки вывода.

tail -F -n0 somefile | grep somepattern | awk '{print $3}'

И теперь вы задаетесь вопросом, куда делся ваш вывод ... в зависимости от объема журналов вы можете обнаружить, что получаете вывод, но это будет страница за раз, потому что теперь стандартный вывод grep работает в режиме с полной буферизацией, поэтому awk получает ввод 4 КБ за раз (по умолчанию).

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

tail -F -n0 somefile | grep --line-buffered somepattern | ...

Однако у большинства команд нет аналога --line-buffered. В случае большего количества инструментов с возможностью создания сценариев вы можете использовать функцию для сброса вывода (например, в awk, функция fflush(), который имеет то же имя, что и его аналог на C, такие инструменты, как Perl и Python, имеют нечто подобное).

С подобными cut вам, вероятно, не повезло; ... но вы можете попробовать поискать unbuffer, что, я думаю, обеспечивается expect toolchain (никогда не использовал).

Надеюсь, вы нашли это полезным.

Ура, Кэмерон

и вы можете использовать несколько каналов и greps и исключать вещи с помощью grep -v, получить нечувствительность к регистру с помощью grep -i и т. д.

то есть: tail -100f / var / log / messages | grep -V ACPI | grep -i ata

начните следить за 100 строками с конца и продолжайте следовать, сначала исключите любые строки с ACPI, затем покажите строки с ata, ATA или любым их сочетанием.

Еще один удобный вариант - это параметры ABC для строк After, Before и Context (строки до и после).