Changing files on the fly in Linux (writing to input file on a pipe)
Solution 1:
I would guess sed still might create the temp file, but the following might do what you want? (Using strace on this might show you if sed creates a temp file or not).
sed -i '/bar/!d' foo.txt
The exclamation inverts the match, d is for delete, so this removes all lines that don't have bar in them.
Solution 2:
Try using sponge from moreutils like this:
sed "s/root/toor/" /etc/passwd | grep -v joey | sponge /etc/passwd
It collects the whole input before writing to it's output.
Solution 3:
Use >> to preserve the contents.
cat foo.txt | grep bar >> foo.txt
Now that will append to the file.
AFAIK, there is no direct way to prepend data to a file in shell. If you want to prepend you may need to use a temporary file in between.
Solution 4:
Depending on how complex your command line is, you may get mileage out of
cat foo.txt | grep bar | tee -a foo.txt