отслеживать файл журнала, но показывать только определенные строки

отслеживать файл журнала, но показывать только определенные строки

Я отслеживаю файл журнала с флагом -f. Затем я передаю это в grep, чтобы найти только строки, содержащие «X». Это работает отлично. Теперь я хочу снова передать это в другой grep, который удалит все строки, содержащие «Y». Когда я добавляю второй канал, файл перестает обновляться, и похоже, что данные не поступают.

Вот команда, которая работает: tail -f my_file.log | grep "X"

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

Как мне это структурировать, чтобы команда работала?

решение1

Так как вывод 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'

решение2

Обычно я нахожу более полезными awkдля такого рода логических проверок:

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

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

решение3

Другой подход — использовать один grepвызов вместо двух и таким образом избежать проблемы буферизации. Просто используйте регулярное выражение, которое соответствует строкам, состоящим из 0 или более не-Y символов, затем X и затем 0 или более не-Y снова до конца строки"

tail -f /path/to/log | grep '^[^Y]*X[^Y]*$'

Связанный контент