Вопрос: Как применить фильтр к выходу в режиме реального времени `tail -f`?


tail -f path

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

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


47
2017-07-05 09:13


Источник


Маркировка ответов, принятых, помогает другим, кто читает ваши вопросы и их ответы, знать, какой ответ может с большей вероятностью помочь им, если у них есть аналогичный вопрос или проблема. Вы можете вернуться к своим предыдущим вопросам, нажав на свое имя пользователя. - Dennis Williamson


Ответы:


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

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

tail -f path | grep your-search-filter

65
2017-07-05 09:17



Но предположим, что у вас есть 100 строк в хвосте (конец файла), и эти строки - те, которые вы хотите фильтровать. Ваше решение - TraderJoeChicago
Если вы хотите только искать последние 100 строк файла, попробуйте tail -100 path | grep xxx - AddersUK


Короткий ответ: 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}'

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

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

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

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

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

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

Ура, Cameron


10
2017-08-02 10:46



Я очень благодарен за объяснение Зачем это работает в режиме буферизации. Спасибо, спасибо. - Green
@Green спасибо за отзыв - Cameron Kerr


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

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

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

Еще одна удобная опция ABC, для строк After, Before и Context (строки до и после).


2
2017-07-05 20:12