хвостовий файл журналу, але показувати лише певні рядки


29

Я записую файл журналу з прапорцем -f. Потім я перекладаю це на grep, щоб знайти лише рядки, що містять "X". Це працює чудово. Тепер я хочу передати це знову в інший греп, який видалить усі рядки, що містять "Y". Коли я додаю другу трубку, файл перестає оновлюватись і, схоже, ніяких даних не надходить.

Це команда, яка працює: tail -f my_file.log | grep "X"

Це команда, яка не: tail -f my_file.log | grep "X" | grep -v "Y"

Як я повинен структурувати так, щоб команда працювала?


1
спробуйте зробити одну трубу по одній трубі, змінити послідовність, зробити tail -f file|grep -v "Y". якщо вихід нормальний, тоді переходимо до додавання grep "X".
Айзуддін Залі

Відповіді:


38

Оскільки вихід grepбуферизований, використовуйте --line-bufferedпараметр grepвключити буферизацію рядків:

tail -f /path/to/log | grep --line-buffered 'X' | grep -v 'Y'

Якщо у вас grepнемає можливості, ви можете використовувати stdbufяк альтернативу:

tail -f /path/to/log | stdbuf -oL grep 'X' | grep -v 'Y'

1
Мені цікаво, як stdbufрозповідає, libstdbuf.soякі налаштування використовувати.
kasperd

@kasperd: змінні середовища.
Нейт Елдредж

1
@NateEldredge Я вже шукав змінні середовища у виході diff -u <(env) <(stdbuf env)та не знайшов жодної. Але тепер я розумію, що те, що я повинен був перевірити diff -u <(env) <(stdbuf -oL env).
kasperd

Я теж однакова проблема. мій випадок - мені потрібно надрукувати всі рядки, що містять 'aaa' та 'bbb'. Перше рішення не працює. Друге рішення - це робота над тим, що "aaa" існують, а "bbb" не існує. обидва існують не працюють. не даючи виводу. моя команда виглядає так: tail -f test.txt | stdbuf -oL grep 'aaa' | grep 'bbb' вона не дає жодного результату. Чи можете ви мені допомогти.
Нд

18

Я зазвичай вважаю більш корисним awkдля таких логічних перевірок:

tail -f /path/to/log | awk '/X/ && !/Y/'
#                           ^^^    ^^^^
#                   this I want    but not this

Перевірено, маючи дві вкладки, одну, на якій я продовжую писати, seq 20 >> myfileа другу, наприклад tail -f myfile | awk '/3/ && !/13/'.


15

Іншим підходом було б використовувати одне grepвиклик замість двох і таким чином уникати проблеми буферизації. Просто використовуйте регулярні вирази, які відповідають рядкам, що складаються з 0 або більше символів, що не належать до Y, потім X і потім 0 ​​або більше не-Y знову до кінця рядка "

tail -f /path/to/log | grep '^[^Y]*X[^Y]*$'
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.