How to swap filenames in Unix?

This can be done with little helper, just put in .bashrc, .zshrc or where your configs.

function swap() { mv "$1" "$1._tmp" && mv "$2" "$1" && mv "$1._tmp" "$2"; }

And use it as regular function:

$ cat a b
Alfa
Beta

$ swap a b && cat a b
Beta
Alfa

Darwin/Mac OS X has the exchangedata() system call:

The exchangedata() function swaps the contents of the files referenced by path1 and path2 in an atomic fashion. That is, all concurrent processes will either see the pre-exchanged state or the post-exchanged state; they can never see the files in an inconsistent state.

However it only actually works on a few filesystems that specifically support it (such as Apple's HFS and HFS+), and I haven't seen any similar system call on other systems. The portable way to do this is using a third temporary file name, and the operation will not be atomic.


ok, stupid question, but why can't you simply do something like (in a shell script):

mv $fileA $fileA.$$
mv $fileB $fileA
mv $fileA.$$ $fileB

and yes of course it uses a temporary file, but its more concise then the other answers.