简体   繁体   中英

Linux move files without replacing if files exists

In Linux how do I move files without replacing if a particular file already exists in the destination?

I tried the following command:

mv --backup=t <source> <dest>

The file doesn't get replaced but the issue is the extension gets changed because it puts "~" at the back of the filename.

Is there any other way to preserve the extension but only the filename gets changed when moving?

Eg test~1.txt instead of test.txt~1

When the extension gets replaced, subsequently you can't just view a file by double clicking on it.

If you want to make it in shell, without requiring atomicity (so if two shell processes are running the same code at the same time, you could be in trouble), you simply can (using the builtin test(1) feature of your shell)

[ -f destfile.txt ] || mv srcfile.txt destfile.txt

If you require atomicity (something that works when two processes are simultaneously running it), things are quite difficult, and you'll need to call some system calls in C. Look into renameat2(2)

Perhaps you should consider using some version control system like git ?

mv has an option:

-S, --suffix=SUFFIX
          override the usual backup suffix

which you might use; however afaik mv doesn't have a functionality to change part of the filename but not the extension. If you just want to be able to open the backup file with a text editor, you might consider something like:

mv --suffix=.backup.txt <source> <dest>

how this would work: suppose you have

-rw-r--r-- 1 chris users    2 Jan 25 11:43 test2.txt                                                                                                                                                                                                                           
-rw-r--r-- 1 chris users    0 Jan 25 11:42 test.txt

then after the command mv --suffix=.backup.txt test.txt test2.txt you get:

-rw-r--r-- 1 chris users    0 Jan 25 11:42 test2.txt                                                                                                                                                                                                                           
-rw-r--r-- 1 chris users    2 Jan 25 11:43 test2.txt.backup.txt

Guess mv command is quite limited if moving files with same filename.

Below is the bash script that can be used to move and if the file with the same filename exists it will append a number to the filename and the extension is also preserved for easier viewing.

I modified the script that can be found here: https://superuser.com/a/313924

#!/bin/bash
source=$1
dest=$2

file=$(basename $source)
basename=${file%.*}
ext=${file##*.}

if [[ ! -e "$dest/$basename.$ext" ]]; then
      mv "$source" "$dest"
else
      num=1
      while [[ -e "$dest/$basename$num.$ext" ]]; do
            (( num++ ))
      done
      mv "$source" "$dest/$basename$num.$ext" 
fi 

@aandroidtest: if you are able to rely upon a Bash shell script and the source directory (where the files reside presently) and the target directory (where you want to them to move to) are same file system, I suggest you try out a script that I wrote. You can find it at https://github.com/jmmitchell/movestough

In short, the script allows you to move files from a source directory to a target directory while taking into account new files, duplicate (same file name, same contents) files, file collisions (same file name, different contents), as well as replicating needed subdirectory structures. In addition, the script handles file collision renaming in three forms. As an example if, /some/path/somefile.name.ext was found to be a conflicting file. It would be moved to the target directory with a name like one of the following, depending on the deconflicting style chosen (via the -u= or --unique-style= flag):

  • default style : /some/path/somefile.name.ext-< unique string here >
  • style 1 : /some/path/somefile.name.< unique string here >.ext
  • style 2 : /some/path/somefile.< unique string here >.name.ext

Let me know if you have any questions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM