2014-02-24 8 views
6

ich die folgende Struktur haben:Scan-Dateien rekursiv und löschen leere Verzeichnisse in Python

Dir 1 
|___Dir 2 
    |___file 1 
    |___file 2... 
Dir 3 
|___Dir 4 
    |___file 3... 

Ich mag wäre in der Lage sein, jede Datei rekursiv zu finden, verarbeiten Sie die Datei auf meine eigene Weise, einmal getan, löschen Sie die Datei, gehe zum nächsten. Wenn das Verzeichnis leer ist, löschen Sie es ebenso und arbeiten sich nach oben, bis nichts mehr übrig ist.

Nur nicht sicher, wie es weitergeht. Diese

ist, was ich habe:

for root, dirs, files in os.walk(dir): 
    path = root.split('/') 
    for file in files: 
     file = os.path.join(root, file) 
     process_file(file) 
     os.remove(file) 

was in Ordnung ist, aber ich würde dann die subdirs löschen möchten, wenn und nur sie leer sind.

+0

Was haben Sie versucht? Welches Paket verwenden Sie zum Durchsuchen/Navigieren in der Dateistruktur? – JonathanV

+0

Hallo. Du scheinst SO neu zu sein. Wenn Sie möchten, dass die Leute Ihnen helfen, ermutige ich Sie, dass Sie uns den Code zeigen, den Sie bisher geschrieben haben, und wir werden versuchen, Ihnen auf dieser Grundlage zu helfen. – Ketouem

+0

Führen Sie einen 'os.walk' durch, um alle Dateien abzurufen. Führen Sie einen' os.path.join' aus, um den vollständigen Dateipfad zur Verarbeitung zu erhalten. schließlich lösche den root (der alles darunter löscht) – inspectorG4dget

Antwort

5

Nun, ich denke, dies tun wird, muss allerdings laufen os.walk ...

def get_files(src_dir): 
# traverse root directory, and list directories as dirs and files as files 
    for root, dirs, files in os.walk(src_dir): 
     path = root.split('/') 
     for file in files: 
      process(os.path.join(root, file)) 
        os.remove(os.path.join(root, file)) 

def del_dirs(src_dir): 
    for dirpath, _, _ in os.walk(src_dir, topdown=False): # Listing the files 
     if dirpath == src_dir: 
      break 
     try: 
      os.rmdir(dirpath) 
     except OSError as ex: 
      print(ex) 


def main(): 
    get_files(src_dir) 
    del_dirs(src_dir) 


if __name__ == "__main__": 
    main() 
0

Dies ist nur für leere Verzeichnisse zu entfernen und auch einzelne Dateien von Verzeichnissen herausziehen. Es scheint nur einen Teil der Frage zu beantworten, sorry.

Ich habe eine Schleife am Ende hinzugefügt, um weiter zu versuchen, bis es nicht mehr finden kann. Ich habe die Funktion eine Anzahl von entfernten Verzeichnissen zurückgeben lassen.

Mein Zugriff verweigert Fehler wurden durch Fest: shutil.rmtree fails on Windows with 'Access is denied'

import os 
import shutil 


def onerror(func, path, exc_info): 
    """ 
    Error handler for ``shutil.rmtree``. 

    If the error is due to an access error (read only file) 
    it attempts to add write permission and then retries. 

    If the error is for another reason it re-raises the error. 

    Usage : ``shutil.rmtree(path, ignore_errors=False, onerror=onerror)`` 
    """ 
    import stat 

    if not os.access(path, os.W_OK): 
     # Is the error an access error ? 
     os.chmod(path, stat.S_IWUSR) 
     func(path) 
    else: 
     raise 


def get_empty_dirs(path): 
    # count of removed directories 
    count = 0 
    # traverse root directory, and list directories as dirs and files as files 
    for root, dirs, files in os.walk(path): 
     try: 
      # if a directory is empty there will be no sub-directories or files 
      if len(dirs) is 0 and len(files) is 0: 
       print u"deleting " + root 
       # os.rmdir(root) 
       shutil.rmtree(root, ignore_errors=False, onerror=onerror) 
       count += 1 
      # if a directory has one file lets pull it out. 
      elif len(dirs) is 0 and len(files) is 1: 
       print u"moving " + os.path.join(root, files[0]) + u" to " + os.path.dirname(root) 
       shutil.move(os.path.join(root, files[0]), os.path.dirname(root)) 
       print u"deleting " + root 
       # os.rmdir(root) 
       shutil.rmtree(root, ignore_errors=False, onerror=onerror) 
       count += 1 
     except WindowsError, e: 
      # I'm getting access denied errors when removing directory. 
      print e 
     except shutil.Error, e: 
      # Path your moving to already exists 
      print e 
    return count 


def get_all_empty_dirs(path): 
    # loop till break 
    total_count = 0 
    while True: 
     # count of removed directories 
     count = get_empty_dirs(path) 
     total_count += count 
     # if no removed directories you are done. 
     if count >= 1: 
      print u"retrying till count is 0, currently count is: %d" % count 
     else: 
      break 

    print u"Total directories removed: %d" % total_count 
    return total_count 


count = get_all_empty_dirs(os.getcwdu()) # current directory 
count += get_all_empty_dirs(u"o:\\downloads\\") # other directory 
print u"Total of all directories removed: %d" % count 
3

Ich weiß, dieser Beitrag ist älter und kann es keinen Sinn, ein weiteres Beispiel in der Zugabe, sondern auf einen Blick dachte ich, es wäre für ein einfacher Anfänger zu erfassen als einige der anderen hier, weil es keinen Beitritt gibt, es importiert nur ein Modul, und es gibt gute Beispiele für die Verwendung einiger integrierter Funktionen [open() & len()] und neue Python3 String-Formatierung mit str .Format. Es zeigt auch, wie einfach Inhalte in einer Datei in der Funktion print() mit file = filename gefüllt werden.

Dieses Skript scannt ein Stammverzeichnis mit os.walk(), überprüft die Länge von Verzeichnissen und Dateien und führt Bedingungen basierend auf den gefundenen Daten aus. Es erhöht auch einen Zähler, um die Anzahl der verwendeten Verzeichnisse zu bestimmen & leer, und es gibt die Informationen in eine Datei aus. Ich habe dieses Beispiel in Python 3.4 geschrieben und es funktionierte für meine Zwecke. Wenn jemand Ideen zur Verbesserung der Logik hat, dann poste bitte in den Kommentaren, damit wir alle eine neue Perspektive zur Lösung des Problems lernen können.

import os 
#declare the root directory 
root_dir = 'C:\\tempdir\\directory\\directory\\' 
#initialize the counters 
empty_count = 0 
used_count = 0 
#Set the file to write to. 'x' will indicate to create a new file and open it for writing 
outfile = open('C:\\tempdir\\directories.txt', 'x') 
for curdir, subdirs, files in os.walk(root_dir): 
    if len(subdirs) == 0 and len(files) == 0: #check for empty directories. len(files) == 0 may be overkill 
     empty_count += 1 #increment empty_count 
     print('Empty directory: {}'.format(curdir), file = outfile) #add empty results to file 
     os.rmdir(curdir) #delete the directory 
    elif len(subdirs) > 0 and len(files) > 0: #check for used directories 
     used_count += 1 #increment used_count 
     print('Used directory: {}'.format(curdir), file = outfile) #add used results to file 

#add the counters to the file 
print('empty_count: {}\nused_count: {}'.format(empty_count, used_count), file = outfile) 
outfile.close() #close the file 
0
import os 

#Top level of tree you wish to delete empty directories from. 
currentDir = r'K:\AutoCAD Drafting Projects\USA\TX\Image Archive' 

index = 0 

for root, dirs, files in os.walk(currentDir): 
    for dir in dirs: 
     newDir = os.path.join(root, dir) 
     index += 1 
     print str(index) + " ---> " + newDir 

     try: 
      os.removedirs(newDir) 
      print "Directory empty! Deleting..." 
      print " " 
     except: 
      print "Directory not empty and will not be removed" 
      print " " 

Schön und einfach. Der Schlüssel verwendet os.removedirs unter einer try-Anweisung. Es ist bereits rekursiv.

0

Hier ist eine andere Lösung, die ich für effizient halte. Natürlich kann die Effizienz durch Verwendung von os.scandir verbessert werden.

Zuerst definiere ich eine allgemeine Funktion rec_rmdir Funktion (Reccursive RMDIR), die Verzeichnisbaum rekursiv durchsuchen.

  • Die Funktion verarbeitet jede Datei und jedes Unterverzeichnis zuerst.
  • Dann versucht es, das aktuelle Verzeichnis zu entfernen.
  • Das Flag preserve wird verwendet, um das Stammverzeichnis beizubehalten.

Der Algorithmus ist ein Klassiker Depth-first search.

Dann ist es einfach, eine Funktion zu definieren, die die Datei verarbeitet und entfernt.

def process_file_and_remove(path): 
    # process the file 
    # ... 
    os.remove(path) 

Klassische Nutzung:

rec_rmdir("/path/to/root", process_file_and_remove)