How do I make "cp" in OS X not delete files?

3

1

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.

SkippyFlipjack

Posted 2009-10-26T21:28:24.853

Reputation: 253

http://developer.apple.com/mac/library/documentation/Darwin/Reference/ManPages/man1/cp.1.html is the man page for cp. – MDMarra – 2009-10-26T22:01:08.640

1How does Windows merge those two files with the name file1.txt? – Arjan – 2009-10-26T22:01:50.933

1I 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 – 2009-10-26T23:12:10.293

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 – 2009-10-26T23:38:28.477

Answers

5

Don't use cp. Use rsync.

(Apple dev link.)

Matt Ball

Posted 2009-10-26T21:28:24.853

Reputation: 3 322

2

cp does not delete files.

alphazero

Posted 2009-10-26T21:28:24.853

Reputation: 129

2it 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 – 2009-10-26T23:34:00.933

1cp does overwrite files. From a user point of view, this is the same as deleting: an overwritten file is no longer available. – mouviciel – 2009-10-27T19:11:48.597

2

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.)

Doug Harris

Posted 2009-10-26T21:28:24.853

Reputation: 23 578

1This will get you part way there -- it will at least stop unintentionally slamming of files. rsync is a better file sync problem. – Doug Harris – 2009-10-26T22:13:38.930

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 – 2009-10-26T23:35:31.603

1

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.

user78571

Posted 2009-10-26T21:28:24.853

Reputation: 111

I don't know whether to upvote for simplicity and hackiness or downvote for ...brutish hackyness. – Matt Ball – 2009-10-26T21:36:20.220

0

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

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

Grunty

Posted 2009-10-26T21:28:24.853

Reputation: 1

0

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.

metric152

Posted 2009-10-26T21:28:24.853

Reputation:

1You must use -n option to indicate no overwrite of existing files in target directory. – None – 2009-10-26T21:39:20.030

0

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.

Eric

Posted 2009-10-26T21:28:24.853

Reputation: 421