2

Is there a command or option that will allow me to move files without overwriting anything?

For the sake of argument, let us call the file foo.rar.

Now the -n sort of works, it won't overwrite the file. But if a file is there it also won't move the file. I want the file moved except for a system error like otu of disk space.

-b sort of works too. The problem with -b is that if there is a backup file, then -b will clobber the backup file with the new backup file.

So now to add a little meat to the question let us look at our example of foo.rar .Let us do a search for foo.rar in /home. We find 10 different files with that name. What I would like to do is execute the following three commands.

mkdir /tmp/foo_files
find /home -iname "foo.rar" -exec wanted_mv_command {} /tmp/foo_files \;
mv /tmp/foo_files ~/

I want ~/foo_files to contain something like: foo.rar, foo.rar.1, foo.rar.2 ... foo.rar.9 .

I don't care what pattern is used. Instead of foo.rar.# it could for example use foo.#.rar > I jsut want two things. That it indicates what the original name of the file was, and that it shows distinct versions of the file.

2 Answers2

5

Since you're using GNU mv, you can use its --backup option. Just turn on numbered backups.

 mv --backup=numbered file1 file2 your_dir

You can change de suffix via the -S option.

Here is an example:

$ mv --backup=numbered aa/foo bb/foo cc/foo .
$ ls
aa  bb  cc  foo  foo.~1~  foo.~2~
Kira
  • 4,807
3

I just made a small script, let's call it mv_safe.sh. Usage: mv_safe SOURCE_FILE TARGET_DIRECTORY

if test ! -e "$2/$1"
then
  mv -- "$1" "$2"
else
  tries=1
  while test -e "$2/$1.$tries"
  do
    tries=$((tries+1))
  done
  mv -T -- "$1" "$2/$1.$tries"
fi

Warning: this is not atomic. If you run multiple copies of this script in parallel and they happen to target the same file, they may overwrite each other's files.

Example : you have feefoo/foo.bar and foo.bar in your /tmp:

$ ./mv_safe.sh foo.bar feefoo

So here we want to move "safely" foo.bar to feefoo, where the name "foo.bar" is already used. Let's see whaat it gives :

$ ls feefoo
foo.bar   foo.bar.1

Does a usual mv if $1's name is not yet used in $2

Rui F Ribeiro
  • 56,709
  • 26
  • 150
  • 232
joH1
  • 908
  • 3
    Fails terribly if any component of the source or destination contains a space in the filename, such as mv "/tmp/my file.txt" ~ (You can fix that by quoting your variables.) – Chris Davies Dec 19 '15 at 20:49