Sometimes we want to process a file and write back to the same file (aka in-place editing). However, the simplest shell redirection won’t do the job:

cat a.txt > a.txt           # doesn't work


This effectively truncates a.txt.

## With sponge

We can use sponge (included in moreutils) for this kind of work:

cat a.txt | sponge a.txt


This works because sponge soaks up all input before writing the output file.

## Without sponge

What if we don’t have sponge?

We can output to a temporary file and then rename it to the original file:

cat a.txt > b.txt
mv b.txt a.txt


In fact we can do it a little fancier:

{ rm a.txt && cat > a.txt ; } < a.txt


Or even more (if the command doesn’t read from stdin):

{ rm a.txt && cat <(cat) > a.txt ; } < a.txt