Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Copy file or directories recursively in Python

Tags:

python

People also ask

How do you copy a file from a directory to another directory in Python?

Calling shutil. copy(source, destination) will copy the file at the path source to the folder at the path destination. (Both source and destination are strings.) If destination is a filename, it will be used as the new name of the copied file.

What is copy directories recursively?

Recursive means that cp copies the contents of directories, and if a directory has subdirectories they are copied (recursively) too. Without -R , the cp command skips directories.

How do you copy multiple files in Python?

If you don't want to copy the whole tree (with subdirs etc), use or glob. glob("path/to/dir/*. *") to get a list of all the filenames, loop over the list and use shutil. copy to copy each file.

How do I copy a directory and subdirectories?

Copying Directories with cp Command To copy a directory, including all its files and subdirectories, use the -R or -r option.


I suggest you first call shutil.copytree, and if an exception is thrown, then retry with shutil.copy.

import shutil, errno

def copyanything(src, dst):
    try:
        shutil.copytree(src, dst)
    except OSError as exc: # python >2.5
        if exc.errno in (errno.ENOTDIR, errno.EINVAL):
            shutil.copy(src, dst)
        else: raise

To add on Tzot's and gns answers, here's an alternative way of copying files and folders recursively. (Python 3.X)

import os, shutil

root_src_dir = r'C:\MyMusic'    #Path/Location of the source directory
root_dst_dir = 'D:MusicBackUp'  #Path to the destination folder

for src_dir, dirs, files in os.walk(root_src_dir):
    dst_dir = src_dir.replace(root_src_dir, root_dst_dir, 1)
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
    for file_ in files:
        src_file = os.path.join(src_dir, file_)
        dst_file = os.path.join(dst_dir, file_)
        if os.path.exists(dst_file):
            os.remove(dst_file)
        shutil.copy(src_file, dst_dir)

Should it be your first time and you have no idea how to copy files and folders recursively, I hope this helps.


shutil.copy and shutil.copy2 are copying files.

shutil.copytree copies a folder with all the files and all subfolders. shutil.copytree is using shutil.copy2 to copy the files.

So the analog to cp -r you are saying is the shutil.copytree because cp -r targets and copies a folder and its files/subfolders like shutil.copytree. Without the -r cp copies files like shutil.copy and shutil.copy2 do.


The fastest and most elegant way I've found until now is to use the copy_tree function of distutils.dir_util native package:

import distutils.dir_util
from_dir = "foo/bar"
to_dir = "truc/machin"
distutils.dir_util.copy_tree(from_dir, to_dir)

Unix cp doesn't 'support both directories and files':

betelgeuse:tmp james$ cp source/ dest/
cp: source/ is a directory (not copied).

To make cp copy a directory, you have to manually tell cp that it's a directory, by using the '-r' flag.

There is some disconnect here though - cp -r when passed a filename as the source will happily copy just the single file; copytree won't.