คัดลอกไฟล์หลายไฟล์ใน Python


99

วิธีคัดลอกไฟล์ทั้งหมดที่มีอยู่ในไดเร็กทอรีหนึ่งไปยังไดเร็กทอรีอื่นโดยใช้ Python ฉันมีเส้นทางต้นทางและเส้นทางปลายทางเป็นสตริง


คำตอบ:


141

คุณสามารถใช้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)

ปลายทางควรเป็น C: \ myfolder หรือ C: \ myfolder \ filename.ext?
Steve Byrne

4
@StevenByrne อาจเป็นได้ขึ้นอยู่กับว่าคุณต้องการเปลี่ยนชื่อไฟล์ด้วยหรือไม่ ถ้าไม่ใช่แสดงว่าdestเป็นชื่อไดเร็กทอรี shutil.copy(src, dst)"คัดลอกไฟล์ src ไปยังไฟล์หรือไดเร็กทอรี dst .... หาก dst ระบุไดเร็กทอรีไฟล์จะถูกคัดลอกไปยัง dst โดยใช้ชื่อไฟล์พื้นฐานจาก src"

การปรับปรุงเล็กน้อย: ออกจาก src_files แล้วทำfor fn in os.listdir(src)
Timo

32

หากคุณไม่ต้องการคัดลอกโครงสร้างทั้งหมด (ที่มี subdirs ฯลฯ ) ให้ใช้หรือglob.glob("path/to/dir/*.*")เพื่อรับรายชื่อไฟล์ทั้งหมดวนซ้ำในรายการและใช้shutil.copyเพื่อคัดลอกแต่ละไฟล์

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

2
หมายเหตุ: คุณอาจต้องตรวจสอบผลลัพธ์ glob ด้วย os.path.isfile () เพื่อให้แน่ใจว่าเป็นชื่อไฟล์ ดูคำตอบของ GreenMatt ด้วย แม้ว่า glob จะส่งคืนเฉพาะชื่อไฟล์เช่น os.listdir แต่ก็ยังส่งคืนชื่อไดเร็กทอรีเช่นกัน " . 'อาจเพียงพอตราบเท่าที่คุณไม่มีชื่อไฟล์ที่ไม่มีนามสกุลหรือจุดในชื่อไดเรกทอรี
Steven

สิ่งนี้ไม่ได้คัดลอก subdirs
citynorman

14

ดูที่shutil ในเอกสาร Pythonโดยเฉพาะคำสั่งcopytree

หากมีไดเร็กทอรีปลายทางอยู่แล้วให้ลอง:

shutil.copytree(source, destination, dirs_exist_ok=True)

3
คำพูดที่ดี แต่อาจไม่ใช่ตัวเลือกหากมีไดเรกทอรีอยู่แล้วด้วยเหตุผลบางประการเช่นในกรณีของฉัน
Sven

@Sven สำหรับdirs_exist_ok=Trueตัวเลือกที่ลอง
Emadpres

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
ฉันคิดว่าคุณหมายถึงการเขียนทับไม่ใช่การลบล้าง
Mohammad ElNesr

คอนสแตนตินตอบโจทย์ !! ช่วยฉันได้มาก ข้อเสนอแนะอย่างหนึ่งคือให้ใช้ 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)

แก้ไข:shutil.copytree(src, dest)หากคุณสามารถแน่นอนเพียงแค่ใช้ สิ่งนี้ต้องการให้โฟลเดอร์ปลายทางนั้นไม่มีอยู่แล้ว หากคุณต้องการคัดลอกไฟล์ไปยังโฟลเดอร์ที่มีอยู่วิธีการข้างต้นก็ใช้ได้ดี!

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.