Coder Perfect

In bash, what is the quickest way to swap two files?

Problem

Is it possible to swap two files in bash?

Can they be swapped in a more efficient manner than this:

cp old tmp
cp curr old
cp tmp curr
rm tmp

Asked by flybywire

Solution #1

$ mv old tmp && mv curr old && mv tmp curr

is a little more effective!

Function: Wrapped in a reusable shell

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

Answered by Can Bal

Solution #2

Add the following to your.bashrc file:

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

Check see Can Bal’s response if you wish to deal with the possibility of intermediate mv operations failing.

Please note that neither this nor other replies provide an atomic solution because using Linux syscalls and/or popular Linux filesystems, such a solution is impossible to construct. Check out the exchangedata syscall in the Darwin kernel.

Answered by Hardy

Solution #3

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

Answered by cube

Solution #4

Are you sure you want to swap them? I think it’s worth mentioning that mv: can backup overwritten files automatically.

mv new old -b

you’ll get:

old and old~

if you want to have a

old and old.old

-S can be used to shift to a custom suffix.

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

You can really switch them faster using this method, as it only takes 2 mv:

mv new old -b && mv old~ new

Answered by Ɓukasz Rysiak

Solution #5

Combining the best answers, I put this in my ~/.bashrc:

function swap()
{
  tmpfile=$(mktemp $(dirname "$1")/XXXXXX)
  mv "$1" "$tmpfile" && mv "$2" "$1" &&  mv "$tmpfile" "$2"
}

Answered by Leslie Viljoen

Post is based on https://stackoverflow.com/questions/1115904/shortest-way-to-swap-two-files-in-bash