2

我有一个文件 test.log。非常大的日志文件。它具有不同级别的日志记录。例如,tracedebug、和。infowarningerror

显然trace,级别消息只是高速发送垃圾邮件。我想查看所有没有trace级别日志的消息。

所以我这样做了:

cat test.log | grep -v "trace"

效果很好。

现在我想根据某个关键字过滤剩余的消息keyword1

所以我这样做了:

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

效果很好。

现在我想连续获得相同的输出,我想cattail -f.

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

但这不起作用。我根本没有输出。

我究竟做错了什么?以及如何获得我想要的过滤后的“尾部和跟随”输出。

谢谢您的帮助。

(顺便说一句,我正在使用 cygwin ......如果这有任何影响)

4

3 回答 3

3

您遇到了缓冲问题:出于性能原因grep,将在其缓冲区中保留相当多的输出,并将一次性输出整个块。这意味着当从输入中读取一行时,grep一旦它读取(并允许通过)更多行,就会将其发送到 stdout - 当处理正在使用读入的日志文件时,这可能需要相当长的一段时间tail -f.

许多grep变体都有一个开启线缓冲模式的开关,它将单独输出每条线 - 有一些性能损失。例如GNU grep有一个--line-buffered选项来实现这个效果。

只需将该选项(或适合您的版本的选项grep)添加到您的所有grep调用中,只要将匹配的类似添加到日志文件中,您就会看到一些输出。

于 2011-02-03T19:13:05.120 回答
0

您的代码运行良好,只是遇到了缓冲延迟。所以你会看到很长一段时间什么都没有,然后是短暂的大量文本,然后是另一个等待。阅读http://perl.plover.com/FAQs/Buffering.html了解正在发生的事情。

于 2011-02-03T18:57:46.357 回答
0

tail -f遵循文件的“新传入行”。周期性输出永远不会到达管道grep命令(至少不会,直到tail被终止)。

要定期“跟踪”这些日志文件中的更改,您可能希望watch改用:

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

这将每秒更新一次 ( -n 1) 日志文件的最后 20 行。

于 2011-02-03T19:00:26.737 回答