如何“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}'