When running this code:

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

in a terminal, grep finds the word Match. I get the output:


However, when I run the following code:

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

then grep seems to find nothing, at least it prints nothing. Is grep waiting for a newline that will never come? Is there some way of making grep, sed or similar tool capture matches in streams without the newline character?

  • How do you imagine this would work? If there's no newline then how can grep know when to start trying to find a match? If only 'Matc' has been piped to it for example and grep runs, it won't find any matches. Jul 30, 2019 at 14:21
  • It match but try to read the whole line? Jul 30, 2019 at 14:24
  • @JShorthouse Well, that is exactly what I want to know. Is there some way to make grep, or other similar tool, not wait for a newline before matching, or if it indeed does match, then not wait for a newline before writing the match to stdout? Or is that a flawed proposition? If so, what fundamentals am I failing to grasp?
    – fuumind
    Jul 30, 2019 at 14:30
  • - grep waits for the flush. - What version of grep? do you have a --line-buffered? as ingrep --line-buffered "Match".
    – Rinzwind
    Jul 30, 2019 at 14:37
  • @Rinzwind Yes, It does have --line-buffered.
    – fuumind
    Jul 30, 2019 at 14:41

1 Answer 1


Grep mainly looks for lines that contain a match for the given pattern. Depending on the pattern, it may or may not be possible to determine whether a line matches without looking at the whole line. With grep Match, this is possible, but with grep 'Match$', it isn't. With grep -o Match, grep could print Match as soon as it sees it, but with grep -E -o '(Match)+', if grep has read MatchMa, it doesn't know whether tch will follow or not.

Grep does not implement the special cases where it would be possible to write some output before seeing a whole line. (I think it doesn't implement any such special case, but I'm not completely sure: GNU grep has several modes depending on the pattern that behave somewhat differently.) It just reads one whole line before trying to match.

If there's a character that's never appears in matching text and that always (or at least often) appear between matches, transform this character into a newline. (Or into a null byte and use grep -z.)

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

Note the use of stdbuf -o0 to prevent tr from buffering its output. And if you pipe the output of grep, you'll need that for grep as well, or use grep --line-buffered. (--line-buffered buffers the output of grep; it has no impact on how grep reads input, and it's on by default when grep is printing to a terminal.)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .