需要帮助grep输出另一个grep命令

时间:2011-02-03 18:51:46

标签: grep tail cat

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

显然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 ......如果这有任何意义)

3 个答案:

答案 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行。