Skip to main content
Mentioned that I know about `sed -i` and improved my definition according to @ilkkachu's comment.
Source Link

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?

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

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} | sponge $1 }

With it, I can now do:

$ inplace words.txt grep -v e

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?

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 { "${@: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?
Source Link

Is there a command that makes another command "in-place"?

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

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} | sponge $1 }

With it, I can now do:

$ inplace words.txt grep -v e

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?