How to copy into with cp if destination folder already exists?

cp
6,920

Solution 1

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

Solution 2

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'

Solution 3

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.

Solution 4

$ 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:
6,920

Related videos on Youtube

James Mitch
Author by

James Mitch

Hello everyone here, call me james. I am running Connecting Cool news and I like to invite everyone to visit the site every single day. I like stackoverflow because it is my chance to learn this.

Updated on September 18, 2022

Comments

  • James Mitch
    James Mitch almost 2 years

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

    • James Mitch
      James Mitch over 11 years
      If this is the real James Mitch who posted this please say so in this accounts profile ;)
    • James Mitch
      James Mitch over 11 years
      What happens if I or whoever else is using this account will never accept a answer? Will "I" still lose those 100 reputation points?
    • 0xC0000022L
      0xC0000022L over 11 years
      yes you would. See this: askubuntu.com/users/72629/james-mitch?tab=reputation the rep gets deducted immediately when placing a bounty.
  • sourcejedi
    sourcejedi over 11 years
    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
  • muru
    muru about 9 years
    Using -W will tell rsync to skip checking for differences, it might improve performance.