Skopiuj wiele plików w Pythonie

Odpowiedzi:

140

Możesz użyć os.listdir (), aby pobrać pliki w katalogu źródłowym, os.path.isfile (), aby sprawdzić, czy są to zwykłe pliki (w tym dowiązania symboliczne w systemach * nix) i shutil.copy, aby wykonać kopiowanie.

Poniższy kod kopiuje tylko zwykłe pliki z katalogu źródłowego do katalogu docelowego (zakładam, że nie chcesz kopiować żadnych podkatalogów).

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)
GreenMatt
źródło
Czy dest powinno być czymś w rodzaju C: \ myfolder lub C: \ myfolder \ filename.ext?
Steve Byrne
4
@StevenByrne Może być albo, w zależności od tego, czy chcesz również zmienić nazwę pliku. Jeśli nie, destto nazwa katalogu. shutil.copy(src, dst)"kopiuje plik src do pliku lub katalogu dst .... Jeśli dst określa katalog, plik zostanie skopiowany do dst przy użyciu podstawowej nazwy pliku z src."
32

Jeśli nie chcesz kopiować całego drzewa (z podkatalogami itp.), Użyj lub, glob.glob("path/to/dir/*.*")aby uzyskać listę wszystkich nazw plików, zapętl listę i użyj shutil.copydo skopiowania każdego pliku.

for filename in glob.glob(os.path.join(source_dir, '*.*')):
    shutil.copy(filename, dest_dir)
Steven
źródło
2
Uwaga: Być może będziesz musiał sprawdzić wyniki glob za pomocą os.path.isfile (), aby upewnić się, że są to nazwy plików. Zobacz także odpowiedź GreenMatta. Chociaż glob zwraca tylko nazwę pliku, taką jak os.listdir, nadal zwraca również nazwy katalogów. Plik „ . 'może wystarczyć, o ile nie masz nazw plików bez rozszerzeń lub kropek w nazwach katalogów.
Steven
To nie kopiuje
subdirów
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
Константин Бушко
źródło
1
Może pomóc ustne wyjaśnienie twojego kodu
calico_
1
Myślę, że masz na myśli nadpisywanie , a nie zastępowanie
Mohammad ElNesr,
Konstantin świetna odpowiedź !! bardzo mi pomogło. Jedna sugestia: użyć os.sep zamiast '/' (więc działa na systemie innym niż Linux)
Ari
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)
Isaac Ewhuiknebueze
źródło
3

Oto kolejny przykład rekurencyjnej funkcji kopiowania, która umożliwia kopiowanie zawartości katalogu (w tym podkatalogów) po jednym pliku na raz, którego użyłem do rozwiązania tego problemu.

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)

EDYCJA: Jeśli możesz, zdecydowanie użyj shutil.copytree(src, dest). Wymaga to jednak, aby ten folder docelowy jeszcze nie istniał. Jeśli chcesz skopiować pliki do istniejącego folderu, powyższa metoda działa dobrze!

Dustin Michels
źródło