2011-02-03 5 views
2

У меня есть файл test.log. Очень большой файл журнала. Он имеет разные уровни ведения журнала. Например, trace, debug, info, warning и error.нужна помощь с grep на выходе другой команды grep

Понятно, что сообщения уровня trace - это просто спам на высоких скоростях. Я хотел видеть все сообщения без журналов уровней trace.

Так что я сделал это:

cat test.log | grep -v "trace" 

работает хорошо.

Теперь я хочу отфильтровать оставшиеся сообщения на основе определенного ключевого слова keyword1.

Так что я сделал это:

cat test.log | grep -v "trace" | grep "keyword1" 

работает хорошо.

Теперь я хочу получить тот же вывод на постоянной основе, я подумал о замене cat на tail -f.

tail -f test.log | grep -v "trace" | grep "keyword1" 

Но это не сработает. Я вообще ничего не получаю.

Что я делаю неправильно? И как я могу получить желаемый отфильтрованный 'tail & follow' output.

Спасибо за помощь.

(кстати, я использую Cygwin ... если это имеет значение в любом случае)

ответ

3

Вы столкнулись с проблемами буферизации: по соображениям производительности grep сохранит в своем буфере довольно немного вывода и выведет весь кусок за один раз. Это означает, что когда строка считывается с ввода, grep отправит ее на stdout после того, как она прочтет (и пропустит) еще больше строк, что может произойти довольно долгое время при работе с файлом журнала, который читается используя tail -f.

Многие варианты grep имеют переключатель в режим линейного буферизации, который выводит каждую линию самостоятельно - с некоторой потерей производительности. Например, для достижения этого эффекта GNU grep имеет опцию --line-buffered.

Просто добавьте эту опцию (или соответствующую для вашей версии grep) ко всем вашим вызовам grep, и вы увидите некоторый результат, как только соответствующее совпадение будет добавлено в файл журнала.

+1

'-line-buffered' сделал трюк. Благодарю. – bits

0

Ваш код работает нормально, вы просто сталкиваясь с задержками буферные. Таким образом, вы увидите длинный период ничто, за которым последовал короткий всплеск текста, а затем еще одно ожидание. Прочитайте http://perl.plover.com/FAQs/Buffering.html для объяснения того, что происходит.

0

tail -f следует за «новыми входящими строками» файла. Периодический выход никогда не достигнет команд grep с каналами (по крайней мере, до тех пор, пока не закончится tail).

Периодически «следовать» изменения в этих файлах журналов, вы можете использовать вместо watch:

watch -n 1 -- 'tail -n 20 test.log | grep -v trace | grep keyword1' 

Это будет обновляться каждую секунду (-n 1) последние 20 строк файла журнала.

+0

Но согласно вашему объяснению 'tail -n 20 test.log | grep -v trace' тоже не должен работать, но хвост связан с 1 работой grep. но 2 последовательных конвейера grep не работают. – bits

+0

@bits Императивное изменение было от 'tail -f' до' tail -n'. Мой пример хорошо работает с одной, не говоря уже о двухстах цепных гортах ... –