Скопіюйте кілька файлів у Python


95

Як скопіювати всі файли, що знаходяться в одному каталозі, в інший каталог за допомогою Python. У мене є вихідний шлях і шлях призначення як рядок.


Відповіді:


139

Ви можете використовувати os.listdir (), щоб отримати файли у вихідному каталозі, os.path.isfile (), щоб побачити, чи це звичайні файли (включаючи символічні посилання в системах * nix), та shutil.copy для копіювання.

Наступний код копіює лише звичайні файли з вихідного каталогу в цільовий каталог (я припускаю, ви не хочете копіювати підкаталоги).

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)

Чи повинен dest мати щось на зразок C: \ myfolder або C: \ myfolder \ filename.ext?
Стів Берн

4
@StevenByrne Може бути будь-яким, залежно від того, якщо ви також хочете перейменувати файл. Якщо ні, тоді destце назва каталогу. shutil.copy(src, dst)"копіює файл src у файл або каталог dst .... Якщо dst вказує каталог, файл буде скопійовано в dst, використовуючи базове ім'я файлу з src."

30

Якщо ви не хочете копіювати ціле дерево (з підкаталогами тощо), використовуйте або, glob.glob("path/to/dir/*.*")щоб отримати список усіх імен файлів, прокрутіть по списку та shutil.copyскопіюйте кожен файл.

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

2
Примітка: Можливо, вам доведеться перевірити результати глобуса за допомогою os.path.isfile (), щоб переконатися, що це імена файлів. Див. Також відповідь GreenMatt. Незважаючи на те, що glob повертає лише ім'я файлу, як os.listdir, він також повертає імена каталогів. ' . 'шаблону може бути достатньо, якщо у вас немає назв файлів без розширень або крапок в іменах каталогів.
Стівен

Це не копіює
піддиректори


5
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

1
Це може допомогти дати усне пояснення вашого коду
calico_

1
Я думаю, ви маєте на увазі перезапис , а не перевизначення
Мохаммад ЕльНеср

Костянтин чудова відповідь !! мені дуже допомогло. Хоча одна пропозиція: використовувати os.sep замість '/' (тому це працює в ОС, що не є Linux)
Арі,

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

3

Ось ще один приклад функції рекурсивного копіювання, яка дозволяє копіювати вміст каталогу (включаючи підкаталоги) по одному файлу за раз, який я використовував для вирішення цієї проблеми.

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: Якщо ви можете, однозначно просто використовуйте shutil.copytree(src, dest). Для цього потрібно, щоб цільова папка ще не існувала. Якщо вам потрібно скопіювати файли в існуючу папку, вищезазначений метод працює добре!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.