38

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?

2
  • Did you have a look into rsync?
    – bonob
    Apr 16, 2014 at 15:37
  • @bonob I haven't no. I've used it once or twice, but only for getting files remotely. Apr 16, 2014 at 15:40

4 Answers 4

39

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 :'(

2
  • Haha, this one worked! rsync apparently is the bomb. Apr 16, 2014 at 17:07
  • 3
    Yes 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
    Apr 16, 2014 at 17:12
25

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

6

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)
1
  • I've tried using -n, however it doesn't allow me to filter by *.js files. Apr 16, 2014 at 15:53
3

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

1
  • This will answer n only once. Better use yes n | ... instead of echo n | ...
    – Ruslan
    Sep 5, 2021 at 16:02

You must log in to answer this question.

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