Python-Przenoszenie i nadpisywanie plików i folderów

Mam katalog, 'DST Directory', który ma pliki i foldery w nim i mam 'src Directory', który ma również pliki i foldery w nim. To, co chcę zrobić, to przenieść zawartość 'katalogu src' do 'katalogu Dst' i nadpisać wszystkie pliki, które istnieją o tej samej nazwie. Na przykład ' Src Directory \ file.txt 'musi zostać przeniesiony do' DST Directory\ ' i nadpisać istniejący plik.txt. To samo dotyczy niektórych folderów, przenoszenie folderu i łączenie zawartości z tym samym folderem w 'dst katalog "

Obecnie używam shutil.Przenieś, aby przenieść zawartość src do dst, ale nie zrobi tego, jeśli pliki już istnieją i nie połączy folderów; po prostu umieści folder wewnątrz istniejącego folderu.

Update: aby wszystko było jaśniejsze; to, co robię, to rozpakowywanie archiwum do katalogu Dst, a następnie przenoszenie zawartości katalogu Src i reszipowanie, skutecznie aktualizowanie plików w archiwum zip. Będzie to powtarzane przy dodawaniu nowych plików lub nowych wersji plików itp. Dlatego trzeba nadpisać i scalić

Solved: rozwiązałem swój problem używając distutils.dir_util.copy_tree (src, dst), kopiuje foldery i pliki z katalogu src do katalogu dst i nadpisuje / łączy w razie potrzeby. Mam nadzieję, że to pomoże niektórym!

Hope that makes sense, dzięki!

Author: Artharos, 2011-09-14

6 answers

Zamiast tego użyj copy(), która jest gotowa do nadpisania plików docelowych. Jeśli chcesz, aby pierwsze drzewo zniknęło, po prostu rmtree() to oddzielnie, gdy skończysz iterację nad nim.

Http://docs.python.org/library/shutil.html#shutil.copy

Http://docs.python.org/library/shutil.html#shutil.rmtree

Update:

Wykonaj os.walk() nad drzewem źródłowym. Dla każdego katalogu sprawdź, czy istnieje on po stronie docelowej i os.makedirs() jeśli jest zaginęła. Dla każdego pliku wystarczy shutil.copy(), a plik zostanie utworzony lub nadpisany, w zależności od tego, co jest właściwe.

 38
Author: Brandon Rhodes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-14 17:18:13

To przejdzie przez katalog źródłowy, utworzy wszelkie katalogi, które nie istnieją w katalogu docelowym, i przeniesie pliki ze źródła do katalogu docelowego:

import os
import shutil

root_src_dir = 'Src Directory\\'
root_dst_dir = 'Dst Directory\\'

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.move(src_file, dst_dir)

Wszystkie istniejące pliki zostaną najpierw usunięte (przez os.remove), zanim zostaną zastąpione przez odpowiedni plik źródłowy. Wszelkie pliki lub katalogi, które już istnieją w miejscu docelowym, ale nie w źródle, pozostaną nietknięte.

 46
Author: Ray Vega,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-15 12:46:02

Ponieważ żadna z powyższych nie działała dla mnie, więc napisałem własną funkcję rekurencyjną. Wywołanie funkcji copyTree (dir1, dir2) do scalania katalogów. Uruchom na wielu platformach Linux i Windows.

def forceMergeFlatDir(srcDir, dstDir):
    if not os.path.exists(dstDir):
        os.makedirs(dstDir)
    for item in os.listdir(srcDir):
        srcFile = os.path.join(srcDir, item)
        dstFile = os.path.join(dstDir, item)
        forceCopyFile(srcFile, dstFile)

def forceCopyFile (sfile, dfile):
    if os.path.isfile(sfile):
        shutil.copy2(sfile, dfile)

def isAFlatDir(sDir):
    for item in os.listdir(sDir):
        sItem = os.path.join(sDir, item)
        if os.path.isdir(sItem):
            return False
    return True


def copyTree(src, dst):
    for item in os.listdir(src):
        s = os.path.join(src, item)
        d = os.path.join(dst, item)
        if os.path.isfile(s):
            if not os.path.exists(dst):
                os.makedirs(dst)
            forceCopyFile(s,d)
        if os.path.isdir(s):
            isRecursive = not isAFlatDir(s)
            if isRecursive:
                copyTree(s, d)
            else:
                forceMergeFlatDir(s, d)
 6
Author: ALLOY,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-10 03:16:52

Jeśli chcesz nadpisać pliki z flagą tylko do odczytu, użyj tego:

def copyDirTree(root_src_dir,root_dst_dir):
"""
Copy directory tree. Overwrites also read only files.
:param root_src_dir: source directory
:param root_dst_dir:  destination directory
"""
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):
            try:
                os.remove(dst_file)
            except PermissionError as exc:
                os.chmod(dst_file, stat.S_IWUSR)
                os.remove(dst_file)

        shutil.copy(src_file, dst_dir)
 3
Author: Vit Bernatik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-20 19:00:34

Spójrz na: os.remove aby usunąć istniejące pliki.

 1
Author: phimuemue,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-09-14 16:37:05

Miałem podobny problem. Chciałem przenieść pliki i struktury folderów i nadpisać istniejące pliki, ale nie usuwać niczego, co znajduje się w docelowej strukturze folderów.

Rozwiązałem to używając os.walk(), rekurencyjnie wywołując moją funkcję i używając shutil.move() na plikach, które chciałem nadpisać i folderach, które nie istniały.

Działa jak shutil.move(), ale z tą zaletą, że istniejące pliki są tylko nadpisywane, ale nie usuwane.

import os
import shutil

def moverecursively(source_folder, destination_folder):
    basename = os.path.basename(source_folder)
    dest_dir = os.path.join(destination_folder, basename)
    if not os.path.exists(dest_dir):
        shutil.move(source_folder, destination_folder)
    else:
        dst_path = os.path.join(destination_folder, basename)
        for root, dirs, files in os.walk(source_folder):
            for item in files:
                src_path = os.path.join(root, item)
                if os.path.exists(dst_file):
                    os.remove(dst_file)
                shutil.move(src_path, dst_path)
            for item in dirs:
                src_path = os.path.join(root, item)
                moverecursively(src_path, dst_path)
 0
Author: the,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-20 14:11:36