Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

Example...

This is what I want.

/tmp $ cp -f -R --verbose /tmp/a /tmp/b
`/tmp/a' -> `/tmp/b'
`/tmp/a/file2' -> `/tmp/b/file2'
`/tmp/a/file1' -> `/tmp/b/file1'

This is what I do not want.

/tmp $ cp -f -R --verbose /tmp/a /tmp/b
`/tmp/a' -> `/tmp/b/a'
`/tmp/a/file2' -> `/tmp/b/a/file2'
`/tmp/a/file1' -> `/tmp/b/a/file1'

How can I let cp behave as if the folder didn't already exist?

(I don't want to delete it beforehand. Just some files from /tmp/a to get copied into /tmp/b without creating a sub folder a inside /tmp/b. So it looks like /tmp/b/file1 /tmp/b/file2 and so on.)

share|improve this question
    
If this is the real James Mitch who posted this please say so in this accounts profile ;) –  James Mitch Feb 13 '13 at 21:36
    
What happens if I or whoever else is using this account will never accept a answer? Will "I" still lose those 100 reputation points? –  James Mitch Feb 14 '13 at 19:54
    
yes you would. See this: askubuntu.com/users/72629/james-mitch?tab=reputation the rep gets deducted immediately when placing a bounty. –  0xC0000022L Feb 15 '13 at 19:54
add comment

4 Answers 4

up vote 3 down vote accepted

Rsync was invented for this kind of thing.

rsync -av --update /source/ /destination

NB: Notice that /source/ has a trailing "/" which picks up file1, file2 and not the folder it is in. /destination doesnt have a trailing. So your solution looks like this:

rsync -av --update /tmp/a/ /tmp/b
share|improve this answer
2  
People use it that way, but it was invented for network transfer. If you're copying gigabytes of files locally, it's a few times slower it could be. Some measurements here: lwn.net/Articles/400489 –  sourcejedi Feb 14 '13 at 19:02
add comment

Assuming Bash you can do

( shopt -s dotglob; cp -f -R --verbose /tmp/a/* /tmp/b/ )

What this does is:

  1. it will make sure globs (the *) catch files with a dot in front. They are considered "hidden" by convention.
  2. * will expand before cp gets to see the command. So if there are two files as in your question the expanded command line will be cp -f -R --verbose /tmp/a/file1 /tmp/a/file1 /tmp/b/
  3. finally the trailing backslash on the destination makes sure that it copies into that folder /tmp/b/.

This method also makes sure you don't have to reset the shell option, because it's being run in a subshell. You can achieve similar results by putting it into a script file instead of executing from the command line.

share|improve this answer
add comment

The -T flag (AKA --no-target-directory) does what you want:

$ cp -R --verbose -T /tmp/a /tmp/b
`/tmp/a/file1' -> `/tmp/b/file1'
`/tmp/a/file2' -> `/tmp/b/file2'
share|improve this answer
add comment
$ cp -r --verbose a/. b
`a/.' -> `b'
`a/./zzz' -> `b/zzz'

$ cp -r --verbose a/. b
`a/./zzz' -> `b/./zzz'

I don't think I've seen this described anywhere; I was just trying different possibilities and found one that worked. For all I know it's a natural consequence of how /. and cp work. (As opposed to the syntax for rsync, mentioned in another answer, which is explicitly documented as a special case).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.