ray@saturn.ucsc.edu (Ray Swartz) (12/15/89)
I have discovered an anomoly that I can't explain and want to know what is going on. If you have a large data file (mine is > 3 Megs) and you want to use grep to find a line in the file, you have to wait for the grep to read through the entire file. To get around this problem, I decided to write a shell script that would get piped the output from the grep and upon reading the first line from the pipe (there will only be one line of output) terminate the grep process. Here's the problem, the shell script (using 'while read data' to read the pipe) doesn't get the output from grep right away. In fact, grep still reads through the entire file before the shell script gets the output. While studying this further, I tried to see if cat had the same problem. The command grep "pattern" bigfile | cat also doesn't show output until the grep command completes. I even tried doing the forking and execing myself and it still waited until the grep finished. Yet, when I run grep by itself, the output comes out to the tty as soon as grep finds a line. Why is it that when grep prints to a terminal the output appears unbuffered and when it is going into a pipe, it appears buffered? Any and all comments appreciated.
cpcahil@virtech.uucp (Conor P. Cahill) (12/16/89)
In article <10064@saturn.ucsc.edu>, ray@saturn.ucsc.edu (Ray Swartz) writes: > Yet, when I run grep by itself, the output comes out to the tty as soon > as grep finds a line. Why is it that when grep prints to a terminal > the output appears unbuffered and when it is going into a pipe, it > appears buffered? Grep writes it's matches to stdout which is buffered by line on output to a terminal and buffered by data block on any other output medium, including pipes. If you really want this functionality, get the gnu grep sources and add a parameter to stop looking after the first match (i.e. only show the first matching record). Or you could make it reall inefficient and turn off all buffering, but I don't recommend this. -- +-----------------------------------------------------------------------+ | Conor P. Cahill uunet!virtech!cpcahil 703-430-9247 ! | Virtual Technologies Inc., P. O. Box 876, Sterling, VA 22170 | +-----------------------------------------------------------------------+
maart@cs.vu.nl (Maarten Litmaath) (12/19/89)
In article <1989Dec16.133416.3855@virtech.uucp> cpcahil@virtech.uucp (Conor P. Cahill) writes:
\... If you really want this functionality, get the gnu grep sources and add
\a parameter to stop looking after the first match [...]
Or use sed:
$ SED="
/$pattern/!d
p
q
"
$ sed "$SED" file
--
Sci.aquaria votes are only poisson distributed in France. (Alan M Stanier) |
Maarten Litmaath @ VU Amsterdam: maart@cs.vu.nl, uunet!mcsun!botter!maart
morrell@hpsal2.HP.COM (Michael Morrell) (12/19/89)
/ hpsal2:comp.unix.questions / cpcahil@virtech.uucp (Conor P. Cahill) / 5:34 am Dec 16, 1989 / If you really want this functionality, get the gnu grep sources and add a parameter to stop looking after the first match (i.e. only show the first matching record). ---------- You could also use sed (as in "sed '<pattern>p;q'") which will stop reading the input after the match. Michael
jba@harald.ruc.dk (Jan B. Andersen) (12/21/89)
ray@saturn.ucsc.edu (Ray Swartz) writes: >Any and all comments appreciated. Use sed: % sed -n '/pattern/p;//q' file It don't answer your question about pipes but it solves the original problem.