96
votes

I have a directory /a/b/c that has files and subdirectories. I need to copy the /a/b/c/* in the /x/y/z directory. What python methods can I use?

I tried shutil.copytree("a/b/c", "/x/y/z"), but python tries to create /x/y/z and raises an error "Directory exists".

4
Are you trying to move or copy the directory over? Your title says move, but your content says copy. Since these are two different things, it matters exactly which one you mean. - Carlos V
Maybe give an example of before and after, to make it clearer what you want the effect to be, as well? - Xymostech
Np. Also, like @Xymostech said, we're slightly unclear on the desired output. Do you want: /x/y/z/a/b/c or /x/y/z/c? Your use of copytree implies the former, but I just want to make sure. - Carlos V
Could you simply delete any /x/y/z/ directory first (shutil.rmtree()) and then do copytree()? - Eric O Lebigot
This is no longer an issue as of Python 3.8 via the copytree's dirs_exist_ok=True flag. See doc - Jay

4 Answers

181
votes

I found this code working:

from distutils.dir_util import copy_tree

# copy subdirectory example
fromDirectory = "/a/b/c"
toDirectory = "/x/y/z"

copy_tree(fromDirectory, toDirectory)

Reference:

3
votes

You can also use glob2 to recursively collect all paths (using ** subfolders wildcard) and then use shutil.copyfile, saving the paths

glob2 link: https://code.activestate.com/pypm/glob2/

3
votes
from subprocess import call

def cp_dir(source, target):
    call(['cp', '-a', source, target]) # Linux

cp_dir('/a/b/c/', '/x/y/z/')

It works for me. Basically, it executes shell command cp.

-12
votes

The python libs are obsolete with this function. I've done one that works correctly:

import os
import shutil

def copydirectorykut(src, dst):
    os.chdir(dst)
    list=os.listdir(src)
    nom= src+'.txt'
    fitx= open(nom, 'w')

    for item in list:
        fitx.write("%s\n" % item)

    fitx.close()

    f = open(nom,'r')
    for line in f.readlines():
        if "." in line:
            shutil.copy(src+'/'+line[:-1],dst+'/'+line[:-1])
        else:
            if not os.path.exists(dst+'/'+line[:-1]):
                os.makedirs(dst+'/'+line[:-1])
                copydirectorykut(src+'/'+line[:-1],dst+'/'+line[:-1])
            copydirectorykut(src+'/'+line[:-1],dst+'/'+line[:-1])
    f.close()
    os.remove(nom)
    os.chdir('..')