如何“grep”连续的stream?

有可能使用连续stream的grep

我的意思是一个tail -f <file>命令,但输出为了保留只有我感兴趣的线的grep

我试过tail -f <file> | grep pattern tail -f <file> | grep pattern但似乎grep只能执行一次tail完成,也就是说永远不会。

打开grep的行缓冲模式。

 tail -f file | grep --line-buffered my_pattern 

我使用tail -f <file> | grep <pattern> tail -f <file> | grep <pattern>

它会等到grep刷新,直到完成(我使用的是Ubuntu)。

我认为你的问题是,grep使用一些输出缓冲。 尝试

 tail -f file | stdbuf -o0 grep my_pattern 

它会将grep的输出缓冲模式设置为无缓冲。

在大多数情况下,你可以tail -f /var/log/some.log |grep foo ,它会工作得很好。

如果您需要在正在运行的日志文件中使用多个grep,并且您发现没有输出,则可能需要将--line-buffered开关插入到中间 grep(s)中,如下所示:

 tail -f /var/log/some.log | grep --line-buffered foo | grep bar 

你可以考虑这个答案作为增强..通常我正在使用

 tail -F <fileName> | grep --line-buffered <pattern> -A 3 -B 5 

-F在文件旋转的情况下更好(如果文件旋转,-f将不能正常工作)

-A和-B对于在模式出现之前和之后获得线是有用的。这些块将出现在虚线分隔符之间

如果你想在整个文件中find匹配(不仅仅是尾巴),而且你希望它坐下来等待任何新的匹配,这很好地工作:

 tail -c +0 -f <file> | grep --line-buffered <pattern> 

-c +0标志表示输出应该从文件的开头( + )开始0字节( -c )。

是的,这实际上工作得很好。 Grep和大多数Unix命令一次只对一行数据stream进行操作。 如果匹配的话,每条从尾部出来的线都将被分析和传递。

sed将是正确的命令( stream编辑器)

tail -n0 -f <file> | sed -n '/search string/p'

然后如果你想要tail命令退出,一旦你find一个特定的string:

tail --pid=$(($BASHPID+1)) -n0 -f <file> | sed -n '/search string/{p; q}'

显然是一个bashism:$ BASHPID将是tail命令的进程ID。 sed命令是在pipe道尾部之后的,所以sed进程ID将是$ BASHPID + 1。

使用awk(另一个伟大的bash实用程序),而不是grep你没有行缓冲选项! 它会不断地从尾部stream出你的数据。

这是你如何使用grep

 tail -f <file> | grep pattern 

这就是你将如何使用awk

 tail -f <file> | awk '/pattern/{print $0}'