I find myself trying to "edit" a file in-place quite a lot in my shell. Say, I want to remove all lines in words.txt that contain the letter e. Then, I would execute:
$ grep -v e words.txt > words-without-e.txt
$ mv words-without-e.txt words.txt
Many people are confused why they are left with an empty file when executing the following (I am not):
$ grep -v e words.txt > words.txt
grep: words.txt: input file is also the output
Some commands have special flags for in-place behaviour, like --in-place (see sed(1)) to allow this. It's possible to use sponge(1), but this requires me to type the file name twice, which I don't like.
$ grep -v e words.txt | sponge words.txt
I have defined a function that I find handy:
function inplace { cat $1 | $"${@:2}" < "$1" | sponge $1 }
With it, I can now do:
$ inplace words.txt grep -v e
I know that this is limited to "stream processing", i.e. commands that take standard input, process it, and produce standard output. But many commands do.
Maybe I looked in the wrong places, but I haven't stumbled across a similar definition yet, especially given how often the question about in-place editing comes up.
- Is there a common utility that serves the same purpose?
- Have you defined such a function? How does your definition look like? What did you call it?
- Why does this not come up more often? Or did I just miss it?