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