Як застосувати фільтр до виведення в реальному часі `хвоста -f '?


60
tail -f path

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

Як до цього підійти?


1
Позначення відповідей як прийнятих допомагає іншим, хто читає ваші запитання та їх відповіді, дізнатися, яка відповідь може скоріше допомогти їм, якщо у них є подібне запитання чи проблема. Ви можете переглянути свої попередні запитання, натиснувши своє ім’я користувача.
Денніс Вільямсон

Відповіді:


84

За допомогою Unix ви можете передавати вихід однієї програми в іншу.

Отже, щоб відфільтрувати хвіст, ви можете використовувати grep:

tail -f path | grep your-search-filter

Але скажімо, у вас в хвості 100 рядків (кінець файлу), і ці рядки - це ті, які ви хочете відфільтрувати. Ваше рішення
TraderJoeChicago

1
Якщо ви хочете шукати лише останні 100 рядків файлу, спробуйте шлях -100 | grep xxx
AddersUK

15

Коротка відповідь: 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отримує вхід 4 кБ за один раз (за замовчуванням).

У цьому випадку ви можете сказати, grepщоб завжди робити рядок stdout буферизованим, використовуючи --line-bufferedпараметр.

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

Однак у більшості команд немає аналога --line-buffered. У випадку з більш інструментами, написаними на скрипті, ви можете використовувати функцію для відмивання результатів (наприклад, в awk, функція є fflush(), яка має те саме ім'я, що і її аналог C, такі інструменти, як Perl і Python, мають щось подібне).

З подібними подобами cutвам, швидше за все, не пощастить; ... але ви можете спробувати пошукати unbuffer, що, на мою думку, щось передбачене expectланцюжком інструментів (я його ніколи не використовував).

Сподіваюся, ви знайшли це корисним.

Ура, Камерон


Я дуже вдячний поясненню того, чому це працює в режимі буферизації ліній. Це відмінне розуміння, дякую.
Зелений

2

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

тобто: хвіст -100f / var / log / messages | grep -V ACPI | греп -і ата

почніть обводити 100 рядків з кінця і продовжуйте виводити хвости, спочатку виключіть будь-які рядки з ACPI, потім покажіть лінії з ата, ATA або будь-яку суміш з них.

Ще одним зручним варіантом є параметри ABC для рядків After, Before та Context (рядки до і після).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.