Does sort support sorting a file in-place, like `sed --in-place`?
sort
has the -o, --output
option that takes a filename as argument. If it is the same as the input file, it writes the result to a temporary file, then overwrites the original input file (exactly the same thing as what sed -i
does).
From GNU sort
info page:
`-o OUTPUT-FILE'
`--output=OUTPUT-FILE'
Write output to OUTPUT-FILE instead of standard output. Normally,
`sort' reads all input before opening OUTPUT-FILE, so you can
safely sort a file in place by using commands like `sort -o F F'
and `cat F | sort -o F'. However, `sort' with `--merge' (`-m')
can open the output file before reading all input, so a command
like `cat F | sort -m -o F - G' is not safe as `sort' might start
writing `F' before `cat' is done reading it.
On newer systems, `-o' cannot appear after an input file if
`POSIXLY_CORRECT' is set, e.g., `sort F -o F'. Portable scripts
should specify `-o OUTPUT-FILE' before any input files.
and from The Open Group Base Specifications Issue 7:
-o output
Specify the name of an output file to be used instead of the standard
output. This file can be the same as one of the input files.
You can use the sponge
function, that first soaks the stdin
and then writes it to a file, like:
sort < f | sponge f
The downside of sponge
is that it will store the output temporary in memory, which can be problematic for large files. Otherwise you have to write it to a file first and then overwrite the original file.
As however is pointed out by other answers, in place modifications are in general not a good idea, since in the middle of a process (for instance the sponge
one), the machine might crash and then you can lose both the original and new file. You better first write it to a different file and then use an atomic mv
(move) instruction.
It's dangerous to overwrite the input file with the output file, because if the program or the system crashes while the file is being written, you've lost both.
A few programs (mostly GNU versions) have an in-place option (e.g. -i
on perl and GNU sed; -o
on GNU sort). They work by putting the data in a temporary file and then moving it into place. For programs that have no such option, Colin Watson's sponge
utility (included in Joey Hess's moreutils) does the job safely for any program (examples: Can I make cut
change a file in place?; How can I make iconv replace the input file with the converted output?).
Only in those rare cases where you can't recreate the original file with the same permissions do I recommend overwriting the file in place. In this case, you'd better save the original input somewhere. And then you can simply process the copy of the input and send it into the original file.
cp -p f ~/f.backup
sort <~/f.backup >|f
rm ~/f.backup # optional