是否可以从没有新行的流中执行 grep 操作?

是否可以从没有新行的流中执行 grep 操作?

运行此代码时:

while true; do printf "Match Unmatch\n"; sleep 1s; done | grep -o "Match"

在终端中,grep找到单词Match.我得到输出:

Match
Match
Match
...

但是,当我运行以下代码时:

while true; do printf "Match Unmatch"; sleep 1s; done | grep -o "Match"

然后grep似乎什么也没发现,至少它什么也没打印。 grep 是否在等待永远不会出现的换行符?有没有某种方法可以使 grep、sed 或类似工具在流中捕获匹配而无需换行符?

答案1

Grep 主要查找包含给定模式匹配项的行。根据模式的不同,可能无法在不查看整行的情况下确定一行是否匹配。对于grep Match,这是可能的,但是对于grep 'Match$',则不可能。使用 时grep -o Match,grep 可以Match一看到就打印,但是使用 时grep -E -o '(Match)+',如果 grep 读到了MatchMa,它不知道是否tch会跟随。

Grep 不实现在看到整行之前可以写入一些输出的特殊情况。 (我认为它没有实现任何这种特殊情况,但我不完全确定:GNU grep 有多种模式,具体取决于行为略有不同的模式。)它在尝试匹配之前只读取一整行。

如果有一个字符从未出现在匹配文本中并且总是(或至少经常)出现在匹配之间,则将该字符转换为换行符。 (或者进入空字节并使用grep -z。)

while true; do printf "Match Unmatch"; sleep 1s; done | stdbuf -o0 tr ' ' '\n' | grep -o "Match"

请注意使用 来stdbuf -o0防止tr缓冲其输出。如果您通过管道传输 grep 的输出,那么 grep 也需要它,或者使用grep --line-buffered. (--line-buffered缓冲输出grep 的;它对 grep 读取输入的方式没有影响,并且当 grep 打印到终端时它默认处于打开状态。)

相关内容