Recursive, Non-Overwriting File Copy?

22

7

I've got a directory that contains a bunch of other folders containing CoffeeScript/ JavaScript files. I'm able to compile the CoffeeScript files into a new folder with the same folder structure fine.

What I want to do is copy all the *.js files in the source folder to the destination folder recursively. I also don't want to overwrite any files that are already present in the destination folder. Any thoughts of how to accomplish this?

I tried using cp -n source/**.js desination/ and cp -Rn source/**.js desination/ after looking at another similar question, but it doesn't seem to be working.

Any idea how to accomplish this?

AlbertEngelB

Posted 2014-04-16T15:04:30.723

Reputation: 686

Did you have a look into rsync? – bonob – 2014-04-16T15:37:26.667

@bonob I haven't no. I've used it once or twice, but only for getting files remotely. – AlbertEngelB – 2014-04-16T15:40:41.383

Answers

25

You could use rsync (it also does local copy)

rsync -r --ignore-existing --include=*/ --include=*.js --exclude=* source/ destination
  • -r to recurse into directories,
  • --ignore-existing to ignore existing files in destination,
  • the include and exclude filters mean: include all directories, include all *.js files, exclude the rest; the first include is needed, otherwise the final exclude will also exclude directories before their content is scanned.

Finally, you can add a -P if you want to watch progress, a --list-only if you want to see what it would copy without actually copying, and a -t if you want to preserve the timestamps.


This is not related, but I learned the rsync command recently, when I moved 15 years of documents from one partition to another. Confident that my files were there, I then wiped the old partition and put some other stuff in there; I realized later that I lost all the timestamps, and discovered the -t flag. Just wanted to share my distress :'(

bonob

Posted 2014-04-16T15:04:30.723

Reputation: 686

Haha, this one worked! rsync apparently is the bomb. – AlbertEngelB – 2014-04-16T17:07:44.223

3Yes it is, I barely know it but just learned a lot about it by trying to answer your question. If you need to go further in the future, you can define complex filters in files and call them in the command for example. You can also have per-directory filters, compress data when copying, and that's just scratching the surface of it! – bonob – 2014-04-16T17:12:20.660

7

This is also achievable using cp. See here:

sudo cp -vnpr /xxx/* /yyy

xxx = source

yyy = destination

v = verbose

n = no clobber (no overwrite)

p = preserve permissions

r = recursive

SEMbyotic

Posted 2014-04-16T15:04:30.723

Reputation: 71

5

Looking at the man pages it seems that you want the -n option.

-n, --no-clobber
   do not overwrite an existing file (overrides the previous -i option)

tantalum

Posted 2014-04-16T15:04:30.723

Reputation: 151

I've tried using -n, however it doesn't allow me to filter by *.js files. – AlbertEngelB – 2014-04-16T15:53:32.827

0

My distro didn't have clobber available, so:

echo n | cp -vipr xxx yyy

xxx = source

yyy = destination

v = verbose

i = interactive (prompt to overwrite) | which is why the command is preceded with "echo n |"

p = preserve permissions

r = recursive

Octavian

Posted 2014-04-16T15:04:30.723

Reputation: 101