我有一个文件test.log。非常大的日志文件。它具有不同级别的日志记录。例如,trace
,debug
,info
,warning
和error
。
显然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"
但这不起作用。我根本没有输出。
我做错了什么?我怎样才能得到我想要的过滤后的'尾巴&按照'输出。
感谢您的帮助。
(顺便说一下,我正在使用cygwin ......如果这有任何意义)
答案 0 :(得分:3)
您遇到缓冲问题:出于性能原因,grep
将在其缓冲区中保留相当多的输出,并将一次性输出整个块。这意味着当从输入中读取一行时,grep
会在读取(并通过)更多行后将其发送到stdout - 这可能在一段时间之后处理日志文件时正在使用tail -f
读入。
许多grep
变体都可以切换到开启行缓冲模式,它会自行输出每一行 - 但会有一些性能损失。例如,GNU grep
有--line-buffered
选项可以达到此效果。
只需将该选项(或适用于您的grep
版本的选项)添加到所有grep
调用中,只要匹配的内容添加到日志文件中,您就会看到一些输出。< / p>
答案 1 :(得分:0)
您的代码工作正常,您只是遇到缓冲延迟。所以你会看到很长一段时间没有任何东西,接着是短暂的大量文本,然后是另一个等待。请阅读http://perl.plover.com/FAQs/Buffering.html,了解正在发生的事情。
答案 2 :(得分:0)
tail -f
跟随文件的“新传入行”。周期性输出永远不会到达管道grep
命令(至少不会,直到tail
终止)。
要定期“关注”这些日志文件中的更改,您可能希望改为使用watch
:
watch -n 1 -- 'tail -n 20 test.log | grep -v trace | grep keyword1'
这将每秒更新(-n 1
)日志文件的最后20行。