Search code examples
linuxshellcommandpipein-place

How do I update a file using commands run against the same file?


As an easy example, consider the following command:

$ sort file.txt 

This will output the file's data in sorted order. How do I put that data right back into the same file? I want to update the file with the sorted results.

This is not the solution:

$ sort file.txt > file.txt

... as it will cause the file to come out blank. Is there a way to update this file without creating a temporary file?

Sure, I could do something like this:

sort file.txt > temp.txt; mv temp.txt file.txt 

But I would rather keep the results in memory until processing is done, and then write them back to the same file. sort actually has a flag that will allow this to be possible:

sort file.txt -o file.txt

...but I'm looking for a solution that doesn't rely on the binary having a special flag to account for this, as not all are guaranteed to. Is there some kind of linux command that will hold the data until the processing is finished?


Solution

  • For sort, you can use the -o option.

    For a more general solution, you can use sponge, from the moreutils package:

    sort file.txt | sponge file.txt
    

    As mentioned below, error handling here is tricky. You may end up with an empty file if something goes wrong in the steps before sponge.

    This is a duplicate of this question, which discusses the solutions above: How do I execute any command editing its file (argument) "in place" using bash?