Shortest way to swap two files in bash

Viewed 43583

Can two files be swapped in bash?

Or, can they be swapped in a shorter way than this:

cp old tmp
cp curr old
cp tmp curr
rm tmp
15 Answers
$ mv old tmp && mv curr old && mv tmp curr

is slightly more efficient!

Wrapped into reusable shell function:

function swap()         
{
    local TMPFILE=tmp.$$
    mv "$1" $TMPFILE && mv "$2" "$1" && mv $TMPFILE "$2"
}

Add this to your .bashrc:

function swap()         
{
    local TMPFILE=tmp.$$
    mv "$1" $TMPFILE
    mv "$2" "$1"
    mv $TMPFILE "$2"
}

If you want to handle potential failure of intermediate mv operations, check Can Bal's answer.

Please note that neither this, nor other answers provide an atomic solution, because it's impossible to implement such using Linux syscalls and/or popular Linux filesystems. For Darwin kernel, check exchangedata syscall.

tmpfile=$(mktemp $(dirname "$file1")/XXXXXX)
mv "$file1" "$tmpfile"
mv "$file2" "$file1"
mv "$tmpfile" "$file2"

do you actually want to swap them? i think its worth to mention that you can automatically backup overwritten file with mv:

mv new old -b

you'll get:

old and old~

if you'd like to have

old and old.old

you can use -S to change ~ to your custom suffix

mv new old -b -S .old
ls
old old.old

using this approach you can actually swap them faster, using only 2 mv:

mv new old -b && mv old~ new

using mv means you have one fewer operations, no need for the final rm, also mv is only changing directory entries so you are not using extra disk space for the copy.

Temptationh then is to implementat a shell function swap() or some such. If you do be extremly careful to check error codes. Could be horribly destructive. Also need to check for pre-existing tmp file.

mv old tmp
mv curr old
mv tmp curr
Related