Wie kopiere ich mit Python ein ganzes Verzeichnis von Dateien in ein vorhandenes Verzeichnis?

209

Führen Sie den folgenden Code aus einem Verzeichnis aus, das ein Verzeichnis mit dem Namen bar(das eine oder mehrere Dateien enthält) und ein Verzeichnis mit dem Namen baz(das auch eine oder mehrere Dateien enthält) enthält. Stellen Sie sicher, dass kein Verzeichnis mit dem Namen vorhanden ist foo.

import shutil
shutil.copytree('bar', 'foo')
shutil.copytree('baz', 'foo')

Es wird scheitern mit:

$ python copytree_test.py 
Traceback (most recent call last):
  File "copytree_test.py", line 5, in <module>
    shutil.copytree('baz', 'foo')
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/shutil.py", line 110, in copytree
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/os.py", line 172, in makedirs
OSError: [Errno 17] File exists: 'foo'

Ich möchte, dass dies so funktioniert, als hätte ich Folgendes eingegeben:

$ mkdir foo
$ cp bar/* foo/
$ cp baz/* foo/

Muss ich verwenden , shutil.copy()jede Datei in kopieren bazin foo? (Nachdem ich den Inhalt von 'bar' bereits in 'foo' mit kopiert habe shutil.copytree()?) Oder gibt es einen einfacheren / besseren Weg?

Daryl Spitzer
quelle
1
Zu Ihrer Information : Hier ist die ursprüngliche Copytree-Funktion, kopieren und patchen Sie sie einfach :)
Schlamar
3
Es gibt ein Python-Problem bezüglich der Änderung shutil.copytree()des Verhaltens , um das Schreiben in ein vorhandenes Verzeichnis zu ermöglichen, aber es gibt einige Verhaltensdetails, die vereinbart werden müssen.
Nick Chammas
2
Nur zu beachten, dass die oben erwähnte Erweiterungsanforderung für Python 3.8 implementiert wurde: docs.python.org/3.8/whatsnew/3.8.html#shutil
ncoghlan

Antworten:

172

Diese Einschränkung des Standards shutil.copytreeerscheint willkürlich und ärgerlich. Problemumgehung:

import os, shutil
def copytree(src, dst, symlinks=False, ignore=None):
    for item in os.listdir(src):
        s = os.path.join(src, item)
        d = os.path.join(dst, item)
        if os.path.isdir(s):
            shutil.copytree(s, d, symlinks, ignore)
        else:
            shutil.copy2(s, d)

Beachten Sie, dass dies nicht vollständig mit dem Standard übereinstimmt copytree:

  • es nicht ehren symlinksund ignoreParameter für das Stammverzeichnis des srcBaumes;
  • Es werden keine shutil.ErrorFehler auf der Stammebene von srcausgelöst.
  • Im Falle von Fehlern beim Kopieren eines Teilbaums wird shutil.Errordieser Teilbaum ausgelöst, anstatt zu versuchen, andere Teilbäume zu kopieren und einzelne zusammen zu erhöhen shutil.Error.
atzz
quelle
50
Vielen Dank! Stimmen Sie zu, dass dies völlig willkürlich erscheint! shutil.copytreemacht ein os.makedirs(dst)am Start. Kein Teil des Codes hätte tatsächlich ein Problem mit einem bereits vorhandenen Verzeichnis. Dies muss geändert werden. exist_ok=False
Geben Sie
6
Dies ist eine gute Antwort - aber auch die Antwort von Mital Vora unten ist einen Blick wert. Sie haben copytree rekursiv aufgerufen, anstatt shutil.copytree () aufzurufen, da sonst dasselbe Problem auftritt. Erwägen Sie möglicherweise, Antworten zusammenzuführen oder auf Mital Voras zu aktualisieren.
PJeffes
4
Dies schlägt fehl, wenn ein Pfad angegeben wird, der ein Verzeichnis enthält, das im Ziel nicht leer ist. Vielleicht könnte jemand dies mit Schwanzrekursion lösen, aber hier ist eine Änderung an Ihrem Code, die funktioniertdef copyTree( src, dst, symlinks=False, ignore=None): for item in os.listdir(src): s = os.path.join(src, item) d = os.path.join(dst, item) if os.path.isdir(s): if os.path.isdir(d): self.recursiveCopyTree(s, d, symlinks, ignore) else: shutil.copytree(s, d, symlinks, ignore) else: shutil.copy2(s, d)
Sojurn
8
Meh, super nervig. Es ist 4 Jahre später und shutil.copytree hat immer noch diese dumme Einschränkung. :-(
antred
5
@antred ... aber distutils.dir_util.copy_tree(), das sich auch in der stdlib befindet, hat keine solche Einschränkung und verhält sich tatsächlich wie erwartet. Angesichts dessen gibt es keinen zwingenden Grund, zu versuchen, Ihre eigene ( ... normalerweise defekte ) Implementierung abzuwickeln . Die Antwort von Brendan Abel sollte jetzt unbedingt die akzeptierte Lösung sein.
Cecil Curry
257

Hier ist eine Lösung, die Teil der Standardbibliothek ist:

from distutils.dir_util import copy_tree
copy_tree("/a/b/c", "/x/y/z")

Siehe diese ähnliche Frage.

Kopieren Sie den Verzeichnisinhalt in ein Verzeichnis mit Python

Brendan Abel
quelle
5
Dies ist gut, da die Standardbibliothek verwendet wird. Symlinks, Modus und Zeit können ebenfalls beibehalten werden.
Feuer
1
Bemerkte einen kleinen Nachteil. distutils.errors.DistutilsInternalError: mkpath: 'name' must be a stringdh es akzeptiert nicht PosixPath. Müssen str(PosixPath). Wunschliste für Verbesserungen. Abgesehen von dieser Angelegenheit bevorzuge ich diese Antwort.
Sun Bear
@SunBear, Ja, ich denke, das wird bei den meisten anderen Bibliotheken der Fall sein, die Pfade als Zeichenfolgen verwenden. Ein Teil des Nachteils bei der Entscheidung, das PathObjekt nicht von ihm erben zu lassen, strnehme ich an, wie die meisten früheren Implementierungen objektorientierter Pfadobjekte.
Brendan Abel
Übrigens bin ich auf einen dokumentierten Mangel dieser Funktion gestoßen. Es ist hier dokumentiert . Benutzern dieser Funktion wurde empfohlen, sich dessen bewusst zu sein.
Sun Bear
1
Obwohl "technisch öffentlich", beachten Sie bitte, dass die Entwickler von Distutils klargestellt haben (gleicher Link wie @ SunBear's, danke!), Dass dies distutils.dir_util.copy_tree()als Implementierungsdetail von Distutils angesehen wird und nicht für die öffentliche Verwendung empfohlen wird. Die wirkliche Lösung sollte shutil.copytree()darin bestehen, verbessert / erweitert zu werden, um sich ähnlicher zu verhalten distutils.dir_util.copy_tree(), jedoch ohne Mängel. In der Zwischenzeit werde ich weiterhin benutzerdefinierte Hilfsfunktionen verwenden, die denen in anderen Antworten ähneln.
Boris Dalstein
61

Eine leichte Verbesserung gegenüber der Antwort von atzz auf die Funktion, bei der die obige Funktion immer versucht, die Dateien von der Quelle zum Ziel zu kopieren.

def copytree(src, dst, symlinks=False, ignore=None):
    if not os.path.exists(dst):
        os.makedirs(dst)
    for item in os.listdir(src):
        s = os.path.join(src, item)
        d = os.path.join(dst, item)
        if os.path.isdir(s):
            copytree(s, d, symlinks, ignore)
        else:
            if not os.path.exists(d) or os.stat(s).st_mtime - os.stat(d).st_mtime > 1:
                shutil.copy2(s, d)

In meiner obigen Implementierung

  • Erstellen des Ausgabeverzeichnisses, falls noch nicht vorhanden
  • Durchführen des Kopierverzeichnisses durch rekursives Aufrufen meiner eigenen Methode.
  • Wenn wir die Datei tatsächlich kopieren, überprüfe ich, ob die Datei geändert wurde, und nur wir sollten sie kopieren.

Ich benutze die obige Funktion zusammen mit Scons Build. Es hat mir sehr geholfen, da ich beim Kompilieren möglicherweise nicht den gesamten Satz von Dateien kopieren muss, sondern nur die Dateien, die geändert werden.

Mital Vora
quelle
4
Schön, außer dass Sie Symlinks haben und diese als Argumente ignorieren, aber sie werden ignoriert.
Matthew Alpert
Es ist erwähnenswert, dass die Granularität von st_mtime in FAT-Dateisystemen docs.python.org/2/library/os.html bis zu 2 Sekunden betragen kann . Wenn Sie diesen Code in einem Kontext verwenden, in dem Aktualisierungen schnell hintereinander erfolgen, finden Sie möglicherweise keine Überschreibungen.
dgh
Es gibt einen Fehler in der vorletzten Zeile, sollte sein: if not os.path.exists(d) or os.stat(s).st_mtime - os.stat(d).st_mtime > 1:
mpderbec
34

Eine Fusion, die von atzz und Mital Vora inspiriert wurde:

#!/usr/bin/python
import os
import shutil
import stat
def copytree(src, dst, symlinks = False, ignore = None):
  if not os.path.exists(dst):
    os.makedirs(dst)
    shutil.copystat(src, dst)
  lst = os.listdir(src)
  if ignore:
    excl = ignore(src, lst)
    lst = [x for x in lst if x not in excl]
  for item in lst:
    s = os.path.join(src, item)
    d = os.path.join(dst, item)
    if symlinks and os.path.islink(s):
      if os.path.lexists(d):
        os.remove(d)
      os.symlink(os.readlink(s), d)
      try:
        st = os.lstat(s)
        mode = stat.S_IMODE(st.st_mode)
        os.lchmod(d, mode)
      except:
        pass # lchmod not available
    elif os.path.isdir(s):
      copytree(s, d, symlinks, ignore)
    else:
      shutil.copy2(s, d)
  • Gleiches Verhalten wie shutil.copytree , mit Symlinks und ignorierten Parametern
  • Erstellen Sie eine Verzeichniszielstruktur, falls diese nicht vorhanden ist
  • Wird nicht scheitern, wenn dst bereits existiert
Cyrille Pontvieux
quelle
Dies ist viel schneller als die ursprüngliche Lösung, wenn die Verzeichnisverschachtelung tief ist. Danke
Kashif
Haben Sie eine Funktion definiert, die im Code an anderer Stelle auch als "Ignorieren" bezeichnet wird?
KenV99
Sie können jede Funktion mit einem beliebigen Namen definieren, bevor Sie die Copytree-Funktion aufrufen. Diese Funktion (die auch ein Lambda-Ausdruck sein kann) akzeptiert zwei Argumente: einen Verzeichnisnamen und die darin enthaltenen Dateien. Sie sollte eine Iterable von Ignorierdateien zurückgeben.
Cyrille Pontvieux
[x for x in lst if x not in excl]Dies entspricht nicht dem Copytree, bei dem der Glob-Pattern-Matching verwendet wird. en.wikipedia.org/wiki/Glob_(programming)
Konstantin Schubert
2
Das ist toll. Das Ignorieren wurde in der obigen Antwort nicht richtig verwendet.
Keith Holliday
21

Python 3.8 führte das dirs_exist_okArgument ein in shutil.copytree:

Kopieren Sie rekursiv einen gesamten Verzeichnisbaum, der bei src verwurzelt ist, in ein Verzeichnis mit dem Namen dst und geben Sie das Zielverzeichnis zurück. dirs_exist_ok legt fest, ob eine Ausnahme ausgelöst werden soll, falls dst oder ein fehlendes übergeordnetes Verzeichnis bereits vorhanden ist.

Daher sollte dies mit Python 3.8+ funktionieren:

import shutil

shutil.copytree('bar', 'foo')
shutil.copytree('baz', 'foo', dirs_exist_ok=True)
Chris
quelle
dirs_exist_ok=FalseWird der erste Kopierversuch in Copytree nicht standardmäßig fehlschlagen?
Jay
1
@ Jay, nur wenn das Verzeichnis bereits existiert. Ich habe dirs_exist_okden ersten Aufruf weggelassen, um den Unterschied zu veranschaulichen (und weil das Verzeichnis im Beispiel von OP noch nicht vorhanden ist), aber natürlich können Sie es verwenden, wenn Sie möchten.
Chris
Danke, wenn Sie einen Kommentar in der Nähe des ersten Exemplars hinzufügen, würde dies meiner Meinung nach klarer machen :)
Jay,
7

Dokumente geben ausdrücklich an, dass das Zielverzeichnis nicht existieren sollte :

Das von benannte Zielverzeichnis dstdarf noch nicht vorhanden sein. Es werden ebenso wie fehlende übergeordnete Verzeichnisse erstellt.

Ich denke, Ihre beste Wahl ist os.walkdas zweite und alle nachfolgenden Verzeichnisse, copy2Verzeichnisse und Dateien und zusätzliche copystatVerzeichnisse. Immerhin ist es genau das, was copytreein den Dokumenten erklärt wird. Oder Sie könnten copyund copystatjedes Verzeichnis / Datei und os.listdirstatt os.walk.

SilentGhost
quelle
1

Dies ist inspiriert von der ursprünglich besten Antwort von atzz. Ich habe gerade die Logik zum Ersetzen von Dateien / Ordnern hinzugefügt. Es wird also nicht zusammengeführt, sondern die vorhandene Datei / der vorhandene Ordner gelöscht und die neue kopiert:

import shutil
import os
def copytree(src, dst, symlinks=False, ignore=None):
    for item in os.listdir(src):
        s = os.path.join(src, item)
        d = os.path.join(dst, item)
        if os.path.exists(d):
            try:
                shutil.rmtree(d)
            except Exception as e:
                print e
                os.unlink(d)
        if os.path.isdir(s):
            shutil.copytree(s, d, symlinks, ignore)
        else:
            shutil.copy2(s, d)
    #shutil.rmtree(src)

Kommentieren Sie den rmtree aus, um ihn zu einer Verschiebungsfunktion zu machen.

radtek
quelle
0

Hier ist meine Version derselben Aufgabe:

import os, glob, shutil

def make_dir(path):
    if not os.path.isdir(path):
        os.mkdir(path)


def copy_dir(source_item, destination_item):
    if os.path.isdir(source_item):
        make_dir(destination_item)
        sub_items = glob.glob(source_item + '/*')
        for sub_item in sub_items:
            copy_dir(sub_item, destination_item + '/' + sub_item.split('/')[-1])
    else:
        shutil.copy(source_item, destination_item)
Barmaley
quelle
0

Hier ist eine von diesem Thread inspirierte Version, die genauer nachahmt distutils.file_util.copy_file.

updateonlyist ein Bool, wenn True, kopiert nur Dateien mit Änderungsdaten, die neuer als vorhandene Dateien sind, dstsofern nicht aufgeführt, in forceupdatedenen unabhängig kopiert wird.

ignoreund forceupdateerwarten Sie Listen mit Dateinamen oder Ordner- / Dateinamen in Bezug auf src und akzeptieren Platzhalter im Unix-Stil ähnlich globoder fnmatch.

Die Funktion gibt eine Liste der kopierten Dateien zurück (oder würde kopiert, dryrunwenn True).

import os
import shutil
import fnmatch
import stat
import itertools

def copyToDir(src, dst, updateonly=True, symlinks=True, ignore=None, forceupdate=None, dryrun=False):

    def copySymLink(srclink, destlink):
        if os.path.lexists(destlink):
            os.remove(destlink)
        os.symlink(os.readlink(srclink), destlink)
        try:
            st = os.lstat(srclink)
            mode = stat.S_IMODE(st.st_mode)
            os.lchmod(destlink, mode)
        except OSError:
            pass  # lchmod not available
    fc = []
    if not os.path.exists(dst) and not dryrun:
        os.makedirs(dst)
        shutil.copystat(src, dst)
    if ignore is not None:
        ignorepatterns = [os.path.join(src, *x.split('/')) for x in ignore]
    else:
        ignorepatterns = []
    if forceupdate is not None:
        forceupdatepatterns = [os.path.join(src, *x.split('/')) for x in forceupdate]
    else:
        forceupdatepatterns = []
    srclen = len(src)
    for root, dirs, files in os.walk(src):
        fullsrcfiles = [os.path.join(root, x) for x in files]
        t = root[srclen+1:]
        dstroot = os.path.join(dst, t)
        fulldstfiles = [os.path.join(dstroot, x) for x in files]
        excludefiles = list(itertools.chain.from_iterable([fnmatch.filter(fullsrcfiles, pattern) for pattern in ignorepatterns]))
        forceupdatefiles = list(itertools.chain.from_iterable([fnmatch.filter(fullsrcfiles, pattern) for pattern in forceupdatepatterns]))
        for directory in dirs:
            fullsrcdir = os.path.join(src, directory)
            fulldstdir = os.path.join(dstroot, directory)
            if os.path.islink(fullsrcdir):
                if symlinks and dryrun is False:
                    copySymLink(fullsrcdir, fulldstdir)
            else:
                if not os.path.exists(directory) and dryrun is False:
                    os.makedirs(os.path.join(dst, dir))
                    shutil.copystat(src, dst)
        for s,d in zip(fullsrcfiles, fulldstfiles):
            if s not in excludefiles:
                if updateonly:
                    go = False
                    if os.path.isfile(d):
                        srcdate = os.stat(s).st_mtime
                        dstdate = os.stat(d).st_mtime
                        if srcdate > dstdate:
                            go = True
                    else:
                        go = True
                    if s in forceupdatefiles:
                        go = True
                    if go is True:
                        fc.append(d)
                        if not dryrun:
                            if os.path.islink(s) and symlinks is True:
                                copySymLink(s, d)
                            else:
                                shutil.copy2(s, d)
                else:
                    fc.append(d)
                    if not dryrun:
                        if os.path.islink(s) and symlinks is True:
                            copySymLink(s, d)
                        else:
                            shutil.copy2(s, d)
    return fc
KenV99
quelle
0

Die vorherige Lösung weist ein Problem auf, das srcmöglicherweise dstohne Benachrichtigung oder Ausnahme überschrieben wird .

Ich füge eine predict_errorMethode hinzu, um Fehler vor dem Kopieren vorherzusagen. copytreehauptsächlich basierend auf Cyrille Pontvieux 'Version.

Es predict_errorist am besten, zunächst alle Fehler vorherzusagen, es sei denn, Sie möchten, dass bei der Ausführung eine Ausnahme von einer anderen ausgelöst wird, copytreebis alle Fehler behoben sind.

def predict_error(src, dst):  
    if os.path.exists(dst):
        src_isdir = os.path.isdir(src)
        dst_isdir = os.path.isdir(dst)
        if src_isdir and dst_isdir:
            pass
        elif src_isdir and not dst_isdir:
            yield {dst:'src is dir but dst is file.'}
        elif not src_isdir and dst_isdir:
            yield {dst:'src is file but dst is dir.'}
        else:
            yield {dst:'already exists a file with same name in dst'}

    if os.path.isdir(src):
        for item in os.listdir(src):
            s = os.path.join(src, item)
            d = os.path.join(dst, item)
            for e in predict_error(s, d):
                yield e


def copytree(src, dst, symlinks=False, ignore=None, overwrite=False):
    '''
    would overwrite if src and dst are both file
    but would not use folder overwrite file, or viceverse
    '''
    if not overwrite:
        errors = list(predict_error(src, dst))
        if errors:
            raise Exception('copy would overwrite some file, error detail:%s' % errors)

    if not os.path.exists(dst):
        os.makedirs(dst)
        shutil.copystat(src, dst)
    lst = os.listdir(src)
    if ignore:
        excl = ignore(src, lst)
        lst = [x for x in lst if x not in excl]
    for item in lst:
        s = os.path.join(src, item)
        d = os.path.join(dst, item)
        if symlinks and os.path.islink(s):
            if os.path.lexists(d):
                os.remove(d)
            os.symlink(os.readlink(s), d)
            try:
                st = os.lstat(s)
                mode = stat.S_IMODE(st.st_mode)
                os.lchmod(d, mode)
            except:
                pass  # lchmod not available
        elif os.path.isdir(s):
            copytree(s, d, symlinks, ignore)
        else:
            if not overwrite:
                if os.path.exists(d):
                    continue
            shutil.copy2(s, d)
Mithril
quelle
0

Hier ist mein Pass zum Problem. Ich habe den Quellcode für Copytree geändert, um die ursprüngliche Funktionalität beizubehalten, aber jetzt tritt kein Fehler auf, wenn das Verzeichnis bereits vorhanden ist. Ich habe es auch geändert, damit vorhandene Dateien nicht überschrieben werden, sondern beide Kopien beibehalten werden, eine mit einem geänderten Namen, da dies für meine Anwendung wichtig war.

import shutil
import os


def _copytree(src, dst, symlinks=False, ignore=None):
    """
    This is an improved version of shutil.copytree which allows writing to
    existing folders and does not overwrite existing files but instead appends
    a ~1 to the file name and adds it to the destination path.
    """

    names = os.listdir(src)
    if ignore is not None:
        ignored_names = ignore(src, names)
    else:
        ignored_names = set()

    if not os.path.exists(dst):
        os.makedirs(dst)
        shutil.copystat(src, dst)
    errors = []
    for name in names:
        if name in ignored_names:
            continue
        srcname = os.path.join(src, name)
        dstname = os.path.join(dst, name)
        i = 1
        while os.path.exists(dstname) and not os.path.isdir(dstname):
            parts = name.split('.')
            file_name = ''
            file_extension = parts[-1]
            # make a new file name inserting ~1 between name and extension
            for j in range(len(parts)-1):
                file_name += parts[j]
                if j < len(parts)-2:
                    file_name += '.'
            suffix = file_name + '~' + str(i) + '.' + file_extension
            dstname = os.path.join(dst, suffix)
            i+=1
        try:
            if symlinks and os.path.islink(srcname):
                linkto = os.readlink(srcname)
                os.symlink(linkto, dstname)
            elif os.path.isdir(srcname):
                _copytree(srcname, dstname, symlinks, ignore)
            else:
                shutil.copy2(srcname, dstname)
        except (IOError, os.error) as why:
            errors.append((srcname, dstname, str(why)))
        # catch the Error from the recursive copytree so that we can
        # continue with other files
        except BaseException as err:
            errors.extend(err.args[0])
    try:
        shutil.copystat(src, dst)
    except WindowsError:
        # can't copy file access times on Windows
        pass
    except OSError as why:
        errors.extend((src, dst, str(why)))
    if errors:
        raise BaseException(errors)
James
quelle
0

Versuche dies:

import os,shutil

def copydir(src, dst):
  h = os.getcwd()
  src = r"{}".format(src)
  if not os.path.isdir(dst):
     print("\n[!] No Such directory: ["+dst+"] !!!")
     exit(1)

  if not os.path.isdir(src):
     print("\n[!] No Such directory: ["+src+"] !!!")
     exit(1)
  if "\\" in src:
     c = "\\"
     tsrc = src.split("\\")[-1:][0]
  else:
    c = "/"
    tsrc = src.split("/")[-1:][0]

  os.chdir(dst)
  if os.path.isdir(tsrc):
    print("\n[!] The Directory Is already exists !!!")
    exit(1)
  try:
    os.mkdir(tsrc)
  except WindowsError:
    print("\n[!] Error: In[ {} ]\nPlease Check Your Dirctory Path !!!".format(src))
    exit(1)
  os.chdir(h)
  files = []
  for i in os.listdir(src):
    files.append(src+c+i)
  if len(files) > 0:
    for i in files:
        if not os.path.isdir(i):
            shutil.copy2(i, dst+c+tsrc)

  print("\n[*] Done ! :)")

copydir("c:\folder1", "c:\folder2")
Ahmed
quelle
0

Hier ist eine Version, die eine pathlib.PathEingabe als erwartet .

# Recusively copies the content of the directory src to the directory dst.
# If dst doesn't exist, it is created, together with all missing parent directories.
# If a file from src already exists in dst, the file in dst is overwritten.
# Files already existing in dst which don't exist in src are preserved.
# Symlinks inside src are copied as symlinks, they are not resolved before copying.
#
def copy_dir(src, dst):
    dst.mkdir(parents=True, exist_ok=True)
    for item in os.listdir(src):
        s = src / item
        d = dst / item
        if s.is_dir():
            copy_dir(s, d)
        else:
            shutil.copy2(str(s), str(d))

Beachten Sie, dass für diese Funktion Python 3.6 erforderlich ist. Dies ist die erste Version von Python, in os.listdir()der pfadähnliche Objekte als Eingabe unterstützt werden. Wenn Sie frühere Versionen von Python unterstützen müssen, können Sie ersetzen listdir(src)durch listdir(str(src)).

Boris Dalstein
quelle
-2

Ich würde annehmen, der schnellste und einfachste Weg wäre, Python die Systembefehle aufrufen zu lassen ...

Beispiel..

import os
cmd = '<command line call>'
os.system(cmd)

Tar und gzip das Verzeichnis .... entpacken und entpacken Sie das Verzeichnis an der gewünschten Stelle.

Yah?

Kirby
quelle
Wenn Sie unter Windows arbeiten ... laden Sie 7zip herunter .. und verwenden Sie dazu die Befehlszeile. ... wieder nur Vorschläge.
Kirby
31
Systembefehle sollten immer das letzte Mittel sein. Es ist immer besser, die Standardbibliothek zu verwenden, wenn dies möglich ist, damit Ihr Code portabel ist.
Nathanismus