cat, pipes, and filters

Tom Christiansen tchrist at convex.COM
Sat Jun 1 05:56:53 AEST 1991


>From the keyboard of root at progress.COM (Root of all Evil):
:
:Hi,
:
:   I've got a question regarding the way cat behaves in a pipeline.
:(I know, his fur gets all oily %+})  Can I cat the contents of a
:file | pipe the output to a filter (such as sed) | then cat the
:filtered output back to the original file?  I've tried this with the
:following commands:
:
:   cat $FILE | sed s/"$ENTRY"/"$NEWENTRY"/ > $FILE
:
:   cat $FILE | sed s/"$ENTRY"/"$NEWENTRY"/ | cat > $FILE
:
:Both command produce identical results: $FILE is truncated to 0-length.
:
:   However, the following command gives me the result I want:
:
:   cat $FILE | sed s/"$ENTRY"/"$NEWENTRY"/ | tee $FILE 1>/dev/null
:
:So now my script works but I don't really understand why.  I've tested
:this on SunOs 4.1 and Interactive SysV 2.2, no difference.  Is there
:something simple about pipes or I/O redirection that I'm not grasping?

yes.

:Or is this a feature of cat?  
:
:   Any enlightenment would be appreciated.  Also, if you can think of
:a better way to do the same thing (short of using perl), please let
:me know.

hm.... with that kind of proviso, i shouldn't answer.  :-)/2

you need to think about when things are getting opened.  the
shell opens your files before i calls the command.

so either use a temporary, cheat with tee, or else use

    perl -p -i -e "s/$ENTRY/$NEWENTRY/" $FILE

--tom
--
Tom Christiansen		tchrist at convex.com	convex!tchrist
		"So much mail, so little time." 



More information about the Comp.unix.shell mailing list