我能够成功运行此命令:
tail -f my_file.txt | grep foo
Run Code Online (Sandbox Code Playgroud)
它只显示带有字符串 的行foo,并且一直显示它们。
但是当我运行这个命令时:
tail -f my_file.txt | grep foo | grep bar
Run Code Online (Sandbox Code Playgroud)
它不显示任何行,即使有些行同时包含foo和bar。
我知道有一个在一次grep调用中使用多种模式的解决方案,但我想知道为什么这条线失败了。
ilk*_*chu 27
这是因为 C 运行时库的默认行为是缓冲对 stdout 的写入,直到写入完整的数据块(通常是几千字节),除非 stdout 连接到终端。
\n一旦中间的 grep 打印了一个完整的块,您就会得到输出,但是您必须再次等待下一个块填充,依此类推。这是对吞吐量的优化,当左侧命令只执行某些任务并终止而不是等待某些操作时,效果会更好。
\nGNU grep 可以选择--line-buffered关闭该缓冲,因此这应该可以更好地工作:
tail -f my_file.txt | grep --line-buffered foo | grep bar\nRun Code Online (Sandbox Code Playgroud)\n最后一个grep打印到终端,因此默认情况下它是行缓冲的,不需要选项。
有关缓冲问题的通用解决方案,请参阅 关闭管道中的缓冲。
\n在这个有两个 grep 的特殊情况下,您可以使用例如单个 AWK,而不是像评论中提到的 St\xc3\xa9phane Chazelas 那样:
\ntail -f my_file.txt | awk \'/foo/ && /bar/\'\nRun Code Online (Sandbox Code Playgroud)\n(顺便说一句,你也可以做类似的事情,用但没有 来awk \'/foo/ && !/bar/\'捕捉线条。)foobar
在 grep 中做同样的事情会更困难,因为grep -e foo -e bar匹配任何包含或 foo 的 bar行。你需要类似的东西
... |\xc2\xa0grep -E -e \'foo.*bar|bar.*foo\'\nRun Code Online (Sandbox Code Playgroud)\n反而。
\n