如何'grep'连续流?

Mat*_*oli 678 linux bash shell grep tail

这是否可以grep连续使用?

我的意思是一种tail -f <file>命令,但grep在输出上只是为了保留我感兴趣的行.

我已经尝试了,tail -f <file> | grep pattern但似乎grep只能执行一次tail,也就是说永远不会.

小智 1260

grep使用BSD grep(FreeBSD,Mac OS X等)时打开线路缓冲模式

tail -f file | grep --line-buffered my_pattern
Run Code Online (Sandbox Code Playgroud)

你不需要为GNU grep(在几乎任何Linux上使用)执行此操作,因为它将默认刷新(对于其他类似Unix的喜欢,例如SmartOS,AIX或QNX).

  • @MichaelGoldshteyn放轻松.人们赞成它是因为当他们谷歌"grep line buffered"时他们找到了这个页面并且它解决了他们的问题,这可能不完全是问题所提出的问题. (47认同)
  • @MichaelGoldshteyn我在macOS上使用BSD grep而没有`--line-buffered`我得不到输出.但是,经过测试,它看起来像GNU grep做你所描述的.所以像大多数Unix一样,它取决于你的平台的实现.由于问题没有指定平台,**您的**信息似乎是错误的 - 在查看BSD grep的代码并将其与GNU grep进行比较后,行为肯定由--line-buffered选项控制.它只是默认情况下只有GNU grep刷新. (8认同)
  • @MichaelGoldshteyn(以及他的评论的赞成者):我总是遇到`tail -f |的问题 grep`和`--line-buffered`为我解决了这个问题(在Ubuntu 14.04上,GNU grep版本2.16).如果"stdout是tty"逻辑实现了"使用行缓冲"在哪里?在http://git.savannah.gnu.org/cgit/grep.git/tree/src/grep.c中,`line_buffered`仅由参数解析器设置. (5认同)
  • 我来到这里试图grep"strace"的输出.没有`--line-buffered`,它将无法正常工作. (4认同)
  • @MichaelNiemand你可以使用tail -F文件| grep --line-buffered my_pattern (3认同)
  • @MichaelGoldshteyn在某些情况下似乎是真的.例如,我在自动`ssh`会话中远程执行命令(在参数中指定命令).你有更完整的解释吗?谢谢! (3认同)
  • 如果我拖动一个旋转的日志文件,而这正在运行,会发生什么?logrotate能够旋转文件吗? (2认同)
  • 我不认为 --line-bufferred 是默认选项,至少在 ssh 连接上不是。我一直遇到这个问题,直到今天才知道 ---line-bufferred...效果很好! (2认同)

Iri*_*iel 115

tail -f <file> | grep <pattern>一直都在使用.

它将等到grep刷新,直到它完成(我正在使用Ubuntu).

  • Tail不使用输出缓冲 - grep会. (13认同)
  • 不,当输出转到tty设备时,grep不会进行输出缓冲,因为它显然在这个答案中.它有线缓冲!这是正确的答案,应该是接受的答案.有关更多详细信息,请参阅我对当前接受的(**错误**)答案的更长评论. (7认同)
  • 这可能会持续很长一段时间,所以尽量不要急躁. (3认同)
  • @Matthieu:主要取决于您 grep 的内容以及操作系统上的缓冲区有多大。如果 grep 每隔几个小时才匹配一个短字符串,那么距离第一次刷新将需要几天的时间。 (2认同)

XzK*_*Kto 60

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

tail -f file | stdbuf -o0 grep my_pattern
Run Code Online (Sandbox Code Playgroud)

它会将grep的输出缓冲模式设置为unbuffered.

  • 这样做的好处是除了`grep`之外它还可以用于许多其他命令. (7认同)
  • 但是,正如我在使用它后发现的那样,一些命令只在连接到tty时才刷新它们的输出,为此,`unbuffer`(在debian的`expect-dev`包中)是*king*.所以我在stdbuf上使用unbuffer. (4认同)
  • @PeterV.Mørch是的,你是对的,unbuffer有时可以在stdbuf不能的地方工作.但我认为你正试图找到一个"魔术"程序,它将始终解决你的问题而不是理解你的问题.创建虚拟tty是无关的任务.Stdbuf正是我们想要的(设置标准输出缓冲区给出值),而unbuffer做了许多我们可能不想要的隐藏的东西(比较交互式`top`与stdbuf和unbuffer).并且实际上没有"神奇"的解决方案:unbuffer有时也会失败,例如awk使用不同的缓冲区实现(stdbuf也会失败). (4认同)
  • “但是我认为您正在尝试找到一个“魔术”程序,该程序将始终解决您的问题而不是理解您的问题。” - 我觉得你是对的!;-) (2认同)

Ken*_*ams 11

如果你想在整个文件中找到匹配项(而不仅仅是尾部),并且你希望它能够等待任何新的匹配,那么这很有效:

tail -c +0 -f <file> | grep --line-buffered <pattern>
Run Code Online (Sandbox Code Playgroud)

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


Dal*_*son 10

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

如果你需要在正在运行的日志文件中使用多个greps而你发现没有输出,你可能需要将--line-buffered开关粘在你的中间 grep(s)上,如下所示:

tail -f /var/log/some.log | grep --line-buffered foo | grep bar
Run Code Online (Sandbox Code Playgroud)


meb*_*ada 10

您可以将此答案视为增强功能..通常我正在使用

tail -F <fileName> | grep --line-buffered  <pattern> -A 3 -B 5
Run Code Online (Sandbox Code Playgroud)

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

-A 和 -B 可用于在模式出现之前和之后获取行.. 这些块将出现在虚线分隔符之间

但对我来说,我更喜欢做以下事情

tail -F <file> | less
Run Code Online (Sandbox Code Playgroud)

如果您想在流式日志中进行搜索,这将非常有用。我的意思是来回深入地看

  • `grep -C 3 &lt;pattern&gt;`,如果 N 相同,则替换 -A &lt;N&gt; 和 -B &lt;N&gt;。 (6认同)

小智 6

没看到有人为此提供我通常的建议:

less +F <file>
ctrl + c
/<search term>
<enter>
shift + f
Run Code Online (Sandbox Code Playgroud)

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