8

Would like to copy every file from a directory structure to a specific directory only if file does not exist there already.

Got the first part from this Stack Overflow question:

find . -type f -exec cp {} /target-directory \;

How can I check if the file exists or not? If not, copy the file, otherwise skip.

1
  • Do you mean "copy all files in the source tree into a (specific) single directory with no subdirectories"? Or "copy all files in the source tree into a subdirectory of the destination directory similar to where it was in the source tree"? I read the question as the first case - can you edit the question to clarify? (I know you have your answer, but it will be read, and used, by others.) Jun 19, 2017 at 23:05

3 Answers 3

13

You can use -u switch from cp command:

copy only when the SOURCE file is newer than the destination file or when the destination file is missing

or use rsync command with --ignore-existing:

skip updating files that exist on receiver

Example:

rsync --ignore-existing source/* destination/
0
3

Your original command can be rewritten as:

find . -type f -exec bash -c 'test -e /target-directory/"$1" || cp "$1" /target-directory' sh {} \;

The key here is that we call shell with specific commands and pass found file as $1 argument. If test -e /target-directory/"$1" fails, that means file doesn't exist, in which case cp will copy the file.

In general, one can use other commands, as long as the command can verify existence of a file. Some of the other alternatives:

  • /usr/bin/realpath -e /target-directory/"$1" > /dev/null || cp "$1" /target-directory
  • stat >/dev/null /target-directory/"$1" || cp "$1" /target-directory/"$1"
2
  • 2
    Why stat to test for file existence in Bash? Wouldn't test -e be much simpler? Jun 20, 2017 at 7:29
  • @DavidFoerster No particular reason. test command will do too. I'll edit my answer later if i don't forget Jun 20, 2017 at 16:16
0

Read man cp, and use the --no-clobber option to cp.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .