0

I have the folder /a/b/c/d/ and I want to copy d/ into destination /dst/.

However, shutil.copytree("/a/b/c/d", "/dst") produces /dst/a/b/c/d.

I only want /dst, or even /dst/d would suffice, but I don't want all the intermediate folders.

[edit]

As others have noted, copytree does what I want - I had unintentionally added the full path of the source to my destination!

Alex Shroyer
  • 3,499
  • 2
  • 28
  • 54

2 Answers2

1

that is what shutil.copytree does !

shutil.copytree recursively copies an entire directory tree rooted at src to a directory named dst

so the statement in the question :

shutil.copytree("/a/b/c/d", "/dst") produces /dst/a/b/c/d.

is just wrong.this will copy the contents of d (and subdirectories) in to /dst

bitranox
  • 1,664
  • 13
  • 21
  • @Tomerikoo exactly - I ment shutil.copytree. hoosierEE- Your statement "However, shutil.copytree("/a/b/c/d", "/dst") produces /dst/a/b/c/d." is just wrong. It does not. – bitranox Aug 20 '20 at 16:29
  • Well I stand corrected... Indeed from my test also it produced exactly what you wanted @hoosierEE. It copies all contents of the directory into the `dst`. So you will get all contents of `d` inside `/dst/`, not even `/dst/d/` – Tomerikoo Aug 20 '20 at 16:40
1

Given this file structure (on my directory /tmp):

a
└── b
    └── c
        └── d
            ├── d_file1
            ├── d_file2
            ├── d_file3
            └── e
                ├── e_file1
                ├── e_file2
                └── e_file3

If you do shutil.copytree("/tmp/a", "/tmp/dst") you will get:

dst
└── b
    └── c
        └── d
            ├── d_file1
            ├── d_file2
            ├── d_file3
            └── e
                ├── e_file1
                ├── e_file2
                └── e_file3

But if you do shutil.copytree('/tmp/a/b/c/d', '/tmp/dst/d') you get:

dst
└── d
    ├── d_file1
    ├── d_file2
    ├── d_file3
    └── e
        ├── e_file1
        ├── e_file2
        └── e_file3

And shutil.copytree('/tmp/a/b/c/d', '/tmp/dst'):

dst
├── d_file1
├── d_file2
├── d_file3
└── e
    ├── e_file1
    ├── e_file2
    └── e_file3

shutil.copytree also takes relative paths. You can do:

import os
os.chdir('/tmp/a/b/c/d')    
shutil.copytree('.', '/tmp/dst')

Or, since Python 3.6, you can use pathlib arguments to do:

from pathlib import Path
p=Path('/tmp/a/b/c/d')
shutil.copytree(p, '/tmp/dst')

Either case, you get the same result as shutil.copytree('/tmp/a/b/c/d', '/tmp/dst')

dawg
  • 98,345
  • 23
  • 131
  • 206