2010-11-24 4 views
1

Dies ist mein erstes Mal zusammen Hack Bits Code Stücke zu einem Dienstprogramm, das ich brauche (ich bin ein Designer von Beruf) und, obwohl ich fühle ich bin In der Nähe habe ich Probleme, Folgendes zur Arbeit zu bringen.Python - Suche nach Dateien & ZIP, über mehrere Verzeichnisse hinweg

Ich brauche routinemäßig Dateien mit einer .COD-Erweiterung, die innerhalb einer von mir erstellten Verzeichnisstruktur liegen. Als Beispiel kann die Struktur wie folgt aussehen:

(Einzelstammordner) -> (mehrere Ordner) -> (zwei Ordner) -> (ein Ordner) -> COD-Dateien

ich ZIP brauchen Lade alle COD-Dateien in COD.zip hoch und lege diese Zip-Datei in ein Verzeichnis oberhalb der aktuellen Dateien. Ordnerstruktur würde wie folgt aussehen, wenn zum Beispiel getan:

EXPORT Ordner -> 9800 Ordner -> 6 Ordner -> OTA-Ordner (+ neu COD.zip) -> COD-Dateien

Meine Fragen -

Zuerst scheint die COD.zip, die es erstellt, für die COD-Dateien in ihm geeignet zu sein, aber wenn ich es entzippe, gibt es nur 1 .cod innerhalb, aber die Dateigröße dieses ZIP ist die Größe aller zusammen gepackten CODs.

Zweitens brauche ich die COD-Dateien gezippt werden ohne Ordner-Struktur - nur direkt in COD.zip. Momentan erstellt mein Skript eine komplette Verzeichnisstruktur (beginnend mit "users/mysuername/etc etc").

Jede Hilfe wäre sehr dankbar - und Erklärungen noch besser als ich versuche :)

Dank zu lernen.

import os, glob, fnmatch, zipfile 


def scandirs(path): 
for currentFile in glob.glob(os.path.join(path, '*')): 
    if os.path.isdir(currentFile): 
     scandirs(currentFile) 
    if fnmatch.fnmatch(currentFile, '*.cod'): 
      cod = zipfile.ZipFile("COD.zip","a") 
      cod.write(currentFile) 


scandirs(os.getcwd()) 

Antwort

1

Für Problem # 1, glaube ich, Ihr Problem ist wahrscheinlich in diesem Abschnitt:

cod = zipfile.ZipFile("COD.zip","a") 
cod.write(currentFile) 

Sie einen neuen Reißverschluss zu schaffen (und möglicherweise überschreibt die vorhandenen) jedes Mal, wenn Sie gehen ein schreiben neue Datei. Stattdessen möchten Sie die Postleitzahl einmal pro Verzeichnis erstellen und dann wiederholt an sie anhängen (siehe Beispiel unten).

Bei Problem # 2 besteht Ihr Problem darin, dass Sie wahrscheinlich den Dateinamen reduzieren müssen, wenn Sie ihn in das Archiv schreiben. Ein Ansatz wäre, os.chdir zu CD in jedem Verzeichnis in scandirs zu verwenden, wie Sie es betrachten. Ein einfacherer Ansatz besteht darin, das os.path Modul zu verwenden, um den Dateipfad aufzuteilen und den Basisnamen (den Dateinamen ohne den Pfad) zu verwenden. Dann können Sie den zweiten Parameter zu cod.write verwenden, um den Dateinamen zu ändern, der in die tatsächliche Zip eingefügt wird unten).

Also erstellen Sie die Zip-Datei einmal, fügen Sie sie wiederholt an, während Sie die Dateinamen abflachen, und schließen Sie sie dann. Sie müssen auch sicherstellen, dass Sie schließen, oder Sie können nicht alle Ihre Dateien geschrieben bekommen.

Ich habe keine gute Möglichkeit, dies im Moment lokal zu testen, also probier es einfach aus und melde dich zurück. Ich bin mir sicher, dass ich etwas kaputt gemacht habe. ;-)

+0

Ich mache mir Sorgen, dass zu viele Zip-Datei-Handles gleichzeitig geöffnet bleiben.Sie können Ihre Rekursion ein wenig ändern, um zuerst alle Verzeichnisse durchzuspielen und erst dann, wenn keine weiteren Verzeichnisse vorhanden sind, und dann alle Dateien im aktuellen Verzeichnis ausführen, anstatt Dateien und Verzeichnisse gleichzeitig zu mischen. –

+0

Das funktioniert perfekt (abzüglich der leeren Reißverschlüsse)! Ich werde versuchen, sie irgendwie automatisch zu löschen. Vielen Dank! – Rob

+0

3. Mal ist ein Charme! :-D –

1

Der folgende Code hat den gleichen Effekt, ist aber wiederverwendbarer und erstellt nicht mehrere Zip-Dateien.

import os,glob,zipfile 

def scandirs(path, pattern): 
    result = [] 
    for file in glob.glob(os.path.join(path, pattern)): 
     if os.path.isdir(file): 
      result.extend(scandirs(file, pattern)) 
     else: 
      result.append(file) 
    return result 


zfile = zipfile.ZipFile('yourfile.zip','w') 
for file in scandirs(yourbasepath,'*.COD'): 
    print 'Processing file: ' + file 
    zfile.write(file)     # folder structure 
    zfile.write(file, os.path.split(file)[1]) # no folder structure 

zfile.close()