Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Here's the best way to describe this:

dirA
   dir1
      file1.txt
      file3.txt
dirB
   dir1
      file1.txt
      file2.txt

I want to copy the contents of dirB into dirA. cp -R dirB/* dirA would delete dir1 and copy the files, resulting in:

dirA
   dir1
      file1.txt
      file2.txt

But I want to merge them (like it would on Windows) and end up with:

dirA
   dir1
      file1.txt
      file2.txt
      file3.txt

Suggestions? I've tried ditto, but that seems to ignore the recursive part and just dump all the files in the top-level folder.

share|improve this question

migrated from stackoverflow.com Oct 26 '09 at 21:55

This question came from our site for professional and enthusiast programmers.

    
developer.apple.com/mac/library/documentation/Darwin/Reference/… is the man page for cp. – MDMarra Oct 26 '09 at 22:01
1  
How does Windows merge those two files with the name file1.txt? – Arjan Oct 26 '09 at 22:01
1  
I just tested cp -R on Snow Leopard and it will do just what you want. It will overwrite the files in dirA that have the same name but it won't delete any files. – Raynet Oct 26 '09 at 23:12
    
thanks Raynet, I didn't think I was getting that result but I'll check again. the issue here involves subversion. I need to dump a bunch of folders/files into a version-controlled folder, but it needs to leave all existing files there so it doesn't clobber the .svn files. – SkippyFlipjack Oct 26 '09 at 23:38
up vote 5 down vote accepted

Don't use cp. Use rsync.

(Apple dev link.)

share|improve this answer

cp does not delete files.

share|improve this answer
2  
it does in that it overwrites dirA/dir1 with dirB/dir1, rather than just copying the files in that folder. so the behavior is delete-then-copy (when compared with with the Windows way, which is to merge the folders.) – SkippyFlipjack Oct 26 '09 at 23:34
1  
cp does overwrite files. From a user point of view, this is the same as deleting: an overwritten file is no longer available. – mouviciel Oct 27 '09 at 19:11

Use -i option to cp

     -i    Cause cp to write a prompt to the standard error output before
           copying a file that would overwrite an existing file.  If the
           response from the standard input begins with the character `y'
           or `Y', the file copy is attempted.  (The -i option overrides
           any previous -n option.)
share|improve this answer
1  
This will get you part way there -- it will at least stop unintentionally slamming of files. rsync is a better file sync problem. – Doug Harris Oct 26 '09 at 22:13
    
I'll check rsync. the issue with -i (thanks MarkM, I did check the man page first :/) is that I'm dealing with big directory trees and can't confirm every single overwrite. – SkippyFlipjack Oct 26 '09 at 23:35

There's gotta be an elegant way, but as a quick hack: remove write permission from the files in dir1, then do a cp -r.

share|improve this answer
    
I don't know whether to upvote for simplicity and hackiness or downvote for ...brutish hackyness. – Matt Ball Oct 26 '09 at 21:36

dirA dir1 file1.txt file3.txt dirB dir1 file1.txt file2.txt

I would do it this way:

$ cd dirA
$ tar cf - | (cd .../dirB ; tar xf -)

Files get overwritten, directories don't.

share|improve this answer

Erics solution worked but I had to tweak syntax a little:

$ cd dirA
$ tar -cf - ./* | (cd .../dirB ; tar -xf -)
share|improve this answer

I'm doing something similar with an export script. Here is the command I'm using:

cp -R demo_files/. demo

This will merge the files in demo_files with the files in demo. It shouldn't overwrite anything.

share|improve this answer
1  
You must use -n option to indicate no overwrite of existing files in target directory. – Anonymous Oct 26 '09 at 21:39

You must log in to answer this question.

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