关于linux:如何’grep’连续流?

How to 'grep' a continuous stream?

是否可以在连续流中使用grep

我的意思是一种tail -f 命令,但是输出上有grep,以便只保留我感兴趣的行。

我试过tail -f | grep pattern,但似乎grep只有在tail完成后才能执行,也就是说永远不能执行。


使用bsd grep(freebsd、mac os x等)时,打开Grep的线路缓冲模式。

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

对于GNUgrep(几乎在任何Linux上都使用),您不需要这样做,因为它在默认情况下都会刷新(对于其他UNIX,如smartos、aix或qnx,使用ymmv)。


我一直使用tail -f | grep

它将等到grep刷新,而不是等到它完成(我正在使用Ubuntu)。


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

1
tail -f file | stdbuf -o0 grep my_pattern

将GREP的输出缓冲模式设置为无缓冲。


在大多数情况下,您可以使用cx1(3),它将工作得很好。

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

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

如果您想在整个文件中找到匹配项(不仅仅是尾部),并且想让它静坐等待任何新的匹配项,那么这很好地工作:

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

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


没看到有人像我一样主动提出:

1
2
3
4
5
less +F <file>
ctrl + c
/<search term>
<enter>
shift + f

我更喜欢这样,因为你可以随时使用ctrl + c来停止和浏览文件,然后点击shift + f返回到实时的流式搜索。


SED将是更好的选择(流编辑器)

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

然后,如果希望在找到特定字符串后退出tail命令:

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

显然是bashism:$bashpid是tail命令的进程ID。sed命令位于管道尾部之后,因此sed进程ID将为$bashpid+1。


您可以将此答案视为增强。通常我用

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

-如果文件旋转,f更好(如果文件旋转,f将无法正常工作)

-A和-B对于在图案出现之前和之后获取线条很有用。这些块将出现在虚线分隔符之间


这个命令对我有效(suse):

1
mail-srv:/var/log # tail -f /var/log/mail.info |grep --line-buffered LOGIN  >> logins_to_mail

正在收集登录到邮件服务


是的,这真的很管用。Grep和大多数unix命令一次只能在一行上操作流。从尾部出来的每一行都将被分析,如果匹配的话,将被传递。


使用awk(另一个很棒的bash实用程序)而不是grep,因为您没有行缓冲选项!它会不断地从尾部传输数据。

这就是你如何使用grep

1
tail -f <file> | grep pattern

这就是你用锥子的方法

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