Copy multiple files in Python

Question:

How to copy all the files present in one directory to another directory using Python.
I have the source path and the destination path as string.

Asked By: hidayat

||

Answers:

Look at shutil in the Python docs, specifically the copytree command.

If the destination directory already exists, try:

shutil.copytree(source, destination, dirs_exist_ok=True)
Answered By: Doon

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.

for filename in glob.glob(os.path.join(source_dir, '*.*')):
    shutil.copy(filename, dest_dir)
Answered By: Steven

You can use os.listdir() to get the files in the source directory, os.path.isfile() to see if they are regular files (including symbolic links on *nix systems), and shutil.copy to do the copying.

The following code copies only the regular files from the source directory into the destination directory (I’m assuming you don’t want any sub-directories copied).

import os
import shutil
src_files = os.listdir(src)
for file_name in src_files:
    full_file_name = os.path.join(src, file_name)
    if os.path.isfile(full_file_name):
        shutil.copy(full_file_name, dest)
Answered By: GreenMatt
import os
import shutil
os.chdir('C:\') #Make sure you add your source and destination path below

dir_src = ("C:\foooo\")
dir_dst = ("C:\toooo\")

for filename in os.listdir(dir_src):
    if filename.endswith('.txt'):
        shutil.copy( dir_src + filename, dir_dst)
    print(filename)
Answered By: Isaac Ewhuiknebueze
def recursive_copy_files(source_path, destination_path, override=False):
    """
    Recursive copies files from source  to destination directory.
    :param source_path: source directory
    :param destination_path: destination directory
    :param override if True all files will be overridden otherwise skip if file exist
    :return: count of copied files
    """
    files_count = 0
    if not os.path.exists(destination_path):
        os.mkdir(destination_path)
    items = glob.glob(source_path + '/*')
    for item in items:
        if os.path.isdir(item):
            path = os.path.join(destination_path, item.split('/')[-1])
            files_count += recursive_copy_files(source_path=item, destination_path=path, override=override)
        else:
            file = os.path.join(destination_path, item.split('/')[-1])
            if not os.path.exists(file) or override:
                shutil.copyfile(item, file)
                files_count += 1
    return files_count

Here is another example of a recursive copy function that lets you copy the contents of the directory (including sub-directories) one file at a time, which I used to solve this problem.

import os
import shutil

def recursive_copy(src, dest):
    """
    Copy each file from src dir to dest dir, including sub-directories.
    """
    for item in os.listdir(src):
        file_path = os.path.join(src, item)

        # if item is a file, copy it
        if os.path.isfile(file_path):
            shutil.copy(file_path, dest)

        # else if item is a folder, recurse 
        elif os.path.isdir(file_path):
            new_dest = os.path.join(dest, item)
            os.mkdir(new_dest)
            recursive_copy(file_path, new_dest)

EDIT: If you can, definitely just use shutil.copytree(src, dest). This requires that that destination folder does not already exist though. If you need to copy files into an existing folder, the above method works well!

Answered By: Dustin Michels

The top rated answer will throw a runtime error because it tries to join a list with a file name on line 5, when it’s supposed to be joining one string with another string. Create another variable called pathSrc and use that in the join argument. I would also create another variable called pathDest and concatenate it with file_name on the last line. I also imported the method needed from shutil rather than the whole module.

import os
from shutil import copyfile
pathSrc = "the folder where the src files are"
pathDest = "the folder where the dest files are going"
src_files = os.listdir(src)
for file_name in src_files:
    full_file_name = os.path.join(pathSrc, file_name)
    if os.path.isfile(full_file_name):
        shutil.copy(full_file_name, pathDest + file_name)
Answered By: Capitán Planeta

Why not a single line?

import os
import shutil
dest = 'path/to/destination/folder'
src = 'path/to/source/folder/' # mind the '/' at the end
[shutil.copy(src+fn, dest) for fn in os.listdir(src)]

Or with a error handling condition

import os
import shutil
dest = 'path/to/destination/folder'
src = 'path/to/source/folder/' # mind the '/' at the end
try:    
    [shutil.copy(src+fn, dest) for fn in os.listdir(src)]
except:
    print('files already exist in', dest)
Answered By: rmj
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.