Я отслеживаю файл журнала с флагом -f. Затем я добавляю это в grep, чтобы найти только строки, содержащие «X». Это прекрасно работает. Теперь я хочу снова передать это в другой grep, который удалит все строки, содержащие «Y». Когда я добавляю второй канал, файл перестает обновляться, и похоже, что данные не поступают.
Это команда, которая работает: tail -f my_file.log | grep "X"
Эта команда не работает: tail -f my_file.log | grep "X" | grep -v "Y"
Как мне структурировать ее так, чтобы команда работала?
Поскольку продукция 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'
Другой подход должен был бы использовать сингл grep
просьба вместо два и тем самым избежать буферизующей проблемы. Просто используйте регулярные выражения, который соответствует линиям, состоящим из 0 или больше non-Y знаков, затем X и затем 0 или больше non-Ys снова до конца линии»
tail -f /path/to/log | grep '^[^Y]*X[^Y]*
Я обычно нахожу более полезными awk
для подобных логических проверок:
tail -f /path/to/log | awk '/X/ && !/Y/'
# ^^^ ^^^^
# this I want but not this
Проверенный при наличии двух счетов, того, в котором я продолжаю писать seq 20 >> myfile
и другой, имеющий, например tail -f myfile | awk '/3/ && !/13/'
.