2008-10-09 29 views
250

Wie kann ich den Inhalt eines lokalen Ordners in Python löschen?Wie lösche ich den Inhalt eines Ordners in Python?

Das aktuelle Projekt ist für Windows, aber ich würde gerne auch * nix sehen.

+21

Während 'shuthil.rmtree()' den Inhalt des Ordners entfernen kann, wird auch der Ordner entfernt. Wenn der Ordner spezielle Berechtigungen oder Besitzerbits aufweist, erstellen Sie den Ordner einfach neu, nachdem das Löschen nicht hilft. – Rockallite

Antwort

237

Aktualisiert, um nur Dateien zu löschen und die in den Kommentaren vorgeschlagene Methode os.path.join() zu verwenden. Wenn Sie auch Unterverzeichnisse entfernen möchten, entfernen Sie die Kommentarzeichen für die Elif-Anweisung.

import os, shutil 
folder = '/path/to/folder' 
for the_file in os.listdir(folder): 
    file_path = os.path.join(folder, the_file) 
    try: 
     if os.path.isfile(file_path): 
      os.unlink(file_path) 
     #elif os.path.isdir(file_path): shutil.rmtree(file_path) 
    except Exception as e: 
     print(e) 
+1

Ich versuche dies ohne die if-Anweisung, aber ich bekomme "Fehler 5: Zugriff verweigert". Der Ordner befindet sich in Windows 7 und alle Benutzer haben uneingeschränkten Zugriff auf Sicherheitsberechtigungen. – Pitto

+4

Dies wird nicht * alle * den Inhalt des Ordners entfernen, wenn 'if' entfernt wird, werden nur Dateien, symbolische Links und * leere * Verzeichnisse gehen. Fügen Sie stattdessen eine "else" -Klausel hinzu und verwenden Sie 'rmtree' für Verzeichnisse (gemäß dem Code von user609215). – Ian

+8

Das Entfernen der if-Anweisung funktioniert nicht. os.unlink/remove funktioniert nicht in Verzeichnissen, leer oder nicht. Um Verzeichnisse zu behandeln, fügen Sie 'elif os.path.isdir (file_path): shutil hinzu.rmtree (file_path) ' –

8

Sie könnten dafür besser os.walk() verwenden.

os.listdir() unterscheidet nicht zwischen Dateien und Verzeichnissen, und Sie werden schnell in Schwierigkeiten geraten, wenn Sie versuchen, die Verknüpfung aufzuheben. Es gibt ein gutes Beispiel für die Verwendung von os.walk() zum rekursiven Entfernen eines Verzeichnisses here und Hinweise, wie Sie es an Ihre Umstände anpassen können. shutil.rmtree(path, ignore_errors=False, onerror=None)

Docstring:

163

das shutil Modul

import shutil 
shutil.rmtree('/path/to/folder') 

Beschreibung Versuchen Recursively einen Baum Verzeichnis löschen.

Wenn ignore_errors gesetzt ist, werden Fehler ignoriert; Andernfalls, wenn onerror gesetzt ist, wird es genannt den Fehler mit Argumente zu handhaben, wo (func, path, exc_info) func ist os.listdir, os.remove oder os.rmdir; Pfad ist das Argument zu dieser Funktion, die es fehlgeschlagen verursacht hat; und exc_info ist ein Tupel, das von sys.exc_info() zurückgegeben wird. Wenn ignore_errors false ist und onerrorNone ist, wird eine Ausnahme ausgelöst.

+124

Dies löscht nicht nur den Inhalt, sondern auch den Ordner selbst. Ich denke nicht, dass es das ist, was die Frage verlangt. –

+40

Also nur löschen, was darunter ist: shuttil.rmtree ('/ Pfad/zu/Ordner/*') –

+58

Ziemlich spät zum Spiel hier, aber 'shuthil.rmtree ('/ Pfad/zu/Ordner/*')' doesn funktioniert nicht, zumindest unter OSX und Windows XP (Python 2.6.6). Unter OSX meldet Python 2.6.6 "Keine solche Datei oder Verzeichnis". Ich erhalte einen ähnlichen Fehler bei Windows. –

60

Erweitern auf mhawkes Antwort das ist, was ich implementiert habe. Es entfernt den gesamten Inhalt eines Ordners, aber nicht den Ordner selbst. Getestet unter Linux mit Dateien, Ordnern und symbolischen Links, sollte auch unter Windows funktionieren.

import os 
import shutil 

for root, dirs, files in os.walk('/path/to/folder'): 
    for f in files: 
     os.unlink(os.path.join(root, f)) 
    for d in dirs: 
     shutil.rmtree(os.path.join(root, d)) 
+0

Warum 'gehen' und nicht nur Ordnerinhalt auflisten? – Don

+0

Dies ist die richtige Antwort, wenn Sie Verzeichnisse auch löschen möchten. 'walk' wird verwendet, um Dateien zu trennen, die anders behandelt werden müssen.Sie könnten auch' os.listdir' verwenden, aber Sie müssten manuell prüfen, ob jeder Eintrag ein Verzeichnis oder eine Datei ist. – dkamins

+3

Dies ist in der Nähe, aber sowohl os.walk als auch shutil.rmtree sind rekursiv, os.walk ist unnötig, da Sie nur die Dateien und Verzeichnisse auf der obersten Ebene innerhalb des zu bereinigenden Verzeichnisses benötigen. Verwenden Sie einfach eine if-Anweisung für Elemente in os.listdir, um zu sehen, ob Jedes ist eine Datei oder ein Verzeichnis.Verwenden Sie dann remove/unlink und rmtree respectivelyl y. –

111

Sie können dies einfach tun:

import os 
import glob 

files = glob.glob('/YOUR/PATH/*') 
for f in files: 
    os.remove(f) 

Sie können von corse einen anderen Filter in Sie Pfad verwenden, für exemple: /YOU/PATH/*.txt zum Entfernen aller Textdateien in einem Verzeichnis.

+5

@Blueicefield '*' wird keine versteckten Dateien auflisten, wir sollten auch 'glob.glob ('path /.*)' – satoru

+0

hinzufügen, obwohl das Löschen der Liste der Dateien mir einfacher vorkommt: 'import sh; sh.rm (Dateien) ' –

+0

funktionierte wie ein Charme –

41

Mit rmtree und neu erstellen der Ordner könnte funktionieren, aber ich habe Fehler beim Löschen und sofort neu erstellen Ordner auf Netzlaufwerken.

Die vorgeschlagene Lösung, die Walk verwendet, funktioniert nicht, da es rmtree verwendet, um Ordner zu entfernen, und dann versuchen kann, os.unlink für die Dateien zu verwenden, die sich zuvor in diesen Ordnern befanden. Dies verursacht einen Fehler.

Die veröffentlichte glob Lösung wird auch versuchen, nicht leere Ordner zu löschen, was zu Fehlern führt.

ich Ihnen vorschlagen verwenden:

folder_path = '/path/to/folder' 
for file_object in os.listdir(folder_path): 
    file_object_path = os.path.join(folder_path, file_object) 
    if os.path.isfile(file_object_path): 
     os.unlink(file_object_path) 
    else: 
     shutil.rmtree(file_object_path) 
+1

Ihre Lösung wird auch einen Fehler auslösen, wenn es einen Symlink zu einem anderen Verzeichnis gibt. – Blueicefield

+0

@Blueicefield - Können Sie ein Beispiel geben. Ich habe in Linux mit einer symlinked Datei und einem Ordner getestet, und konnte noch keinen Fehler verursachen. – jgoeders

+0

@jgoeders - Wenn es einen symbolischen Link zu einem Verzeichnis gibt, gibt 'os.path.isfile()' '' False' zurück (weil es Symlinks folgt), und Sie werden 'shutil.rmtree()' auf einem Symlink aufrufen , wodurch OSError ("Kann rmtree auf einem symbolischen Link nicht aufrufen") ausgelöst wird. – Rockallite

7

Dies ist die einzige Antwort ist so weit, die:

  • alle symbolischen Links
    • tote Links
    • Links auf Verzeichnisse entfernt
    • Links zu Dateien
  • entfernt Unterverzeichnisse
  • entfernt nicht das übergeordnete Verzeichnis

Code:

for filename in os.listdir(dirpath): 
    filepath = os.path.join(dirpath, filename) 
    try: 
     shutil.rmtree(filepath) 
    except OSError: 
     os.remove(filepath) 

Wie viele andere Antworten, diese nicht versucht, Berechtigungen anpassen Entfernen von Dateien/Verzeichnisse ermöglichen .

5

Ein früherer Kommentar erwähnt auch Verwendung von os.scandir in Python 3.5 +. Zum Beispiel:

+1

'os.path.isdir()' ist keine gültige Möglichkeit, zwischen einem regulären Verzeichnis und einem symbolischen Link zu unterscheiden. Der Aufruf von 'shuthil.rmtree()' auf einem symbolischen Link löst die 'OSError'-Ausnahme aus. – Rockallite

+0

@Rockallite Danke. Du hast recht. Ich habe das Beispiel aktualisiert. –

6

Ich konw es ist ein alter Thread, aber ich habe etwas interessantes von der offiziellen Seite von Python gefunden. Nur für das Teilen einer anderen Idee zum Entfernen aller Inhalte in einem Verzeichnis. Weil ich bei der Verwendung von shuthil.rmtree() einige Autorisierungsprobleme habe und das Verzeichnis nicht entfernen und neu erstellen möchte. Das Adressoriginal ist http://docs.python.org/2/library/os.html#os.walk. Hoffe das könnte jemandem helfen.

def emptydir(top): 
    if(top == '/' or top == "\\"): return 
    else: 
     for root, dirs, files in os.walk(top, topdown=False): 
      for name in files: 
       os.remove(os.path.join(root, name)) 
      for name in dirs: 
       os.rmdir(os.path.join(root, name)) 
5

ich verwenden, um das Problem auf diese Weise zu lösen:

import shutil 
import os 

shutil.rmtree(dirpath) 
os.mkdir(dirpath) 
+4

Dies hat eine grundlegend andere Semantik als die Frage und sollte nicht als gültige Antwort betrachtet werden. – fatuhoku

+0

Verstehen Sie nicht Ihren Kommentar: > "Wie kann ich den Inhalt eines lokalen Ordners in Python löschen. Das aktuelle Projekt ist für Windows, aber ich möchte * nix auch sehen." Ist die Frage. Die Antwort löst die Aufgabe. – ProfHase85

+1

In Bezug darauf denke ich "Löschen Sie den Inhalt des lokalen Ordners" nicht das Entfernen des Ordners selbst. Das selbe Problem wie [diese Antwort] (http://stackoverflow.com/a/186236/590767), außer dass man viele Upvotes bekommt! – fatuhoku

14

Als oneliner:

import os 

# Python 2.7 
map(os.unlink, (os.path.join(mydir,f) for f in os.listdir(mydir))) 

# Python 3+ 
list(map(os.unlink, (os.path.join(mydir,f) for f in os.listdir(mydir)))) 

Eine robustere Lösung als auch für Dateien und Verzeichnisse Buchhaltung wäre (2.7) :

def rm(f): 
    if os.path.isdir(f): return os.rmdir(f) 
    if os.path.isfile(f): return os.unlink(f) 
    raise TypeError, 'must be either file or directory' 

map(rm, (os.path.join(mydir,f) for f in os.listdir(mydir))) 
+1

für große Operationen mit dem Generator kann fraktioniert effizient '' 'map (os.unlink, (os.path.join (mydir, f) für f in os.listdir (mydir)))' '' – user25064

+0

eigentlich versucht zu Verwenden Sie dies, erkannte, dass das Map-Objekt iteriert werden muss, so dass ein Aufruf der Liste (oder etwas, das iteriert wird) wie '' 'liste (map (os.unlink, (os.path.join (mydir, f) für f) erforderlich ist in os.listdir (mydir)))) '' ' – user25064

+0

Erste in der Antwort enthalten, zweite macht für mich keinen Sinn. Warum sollten Sie über eine Funktion iterieren, die einem Iterable zugeordnet ist? Karte macht das. – fmonegaglia

5

Noch Anot ihre Lösung:

import sh 
sh.rm(sh.glob('/path/to/folder/*')) 
+3

https://pypi.python.org/pypi/sh/0.01 aufgenommen – 0atman

10

Hinweise: falls jemand über meine Antwort gestimmt, ich habe hier etwas zu erklären.

  1. Jeder mag kurze 'n' einfache Antworten. Manchmal ist die Realität jedoch nicht so einfach.
  2. Zurück zu meiner Antwort. Ich weiß, shutil.rmtree() könnte verwendet werden, um einen Verzeichnisbaum zu löschen. Ich habe es oft in meinen eigenen Projekten verwendet. Aber Sie müssen erkennen, dass das Verzeichnis selbst auch durch shutil.rmtree() gelöscht wird. Während dies für einige akzeptabel sein könnte, ist es keine gültige Antwort für Löschen des Inhalts eines Ordners (ohne Nebenwirkungen).
  3. Ich werde Ihnen ein Beispiel für die Nebenwirkungen zeigen. Angenommen, Sie haben ein Verzeichnis mit benutzerdefiniert Besitzer und Modus Bits, wo es viele Inhalte gibt. Dann löschen Sie es mit shutil.rmtree() und neu erstellen Sie es mit os.mkdir(). Und Sie erhalten ein leeres Verzeichnis mit default (geerbt) Besitzer und Modus Bits statt. Während Sie möglicherweise das Recht haben, den Inhalt und sogar das Verzeichnis zu löschen, können Sie möglicherweise die ursprünglichen Besitzer- und Modusbits für das Verzeichnis nicht zurücksetzen (z. B. wenn Sie kein Superuser sind).
  4. Schließlich, geduldig sein und den Code lesen. Es ist lang und hässlich (in Sicht), aber erwiesen sich als zuverlässig und effizient (im Einsatz).

Hier ist eine lange und hässlich, aber zuverlässige und effiziente Lösung.

Es löst einige Probleme, die von den anderen Beantworter nicht angesprochen werden:

  • Es behandelt richtig symbolische Links, einschließlich nicht shutil.rmtree() auf einen symbolischen Link aufrufen (die den os.path.isdir() Test bestehen, wenn es um eine Links Verzeichnis, auch das Ergebnis von os.walk() enthält symbolische verknüpfte Verzeichnisse.
  • Es behandelt schreibgeschützte Dateien nett.

Hier ist der Code (die einzige nützliche Funktion ist clear_dir()):

import os 
import stat 
import shutil 


# http://stackoverflow.com/questions/1889597/deleting-directory-in-python 
def _remove_readonly(fn, path_, excinfo): 
    # Handle read-only files and directories 
    if fn is os.rmdir: 
     os.chmod(path_, stat.S_IWRITE) 
     os.rmdir(path_) 
    elif fn is os.remove: 
     os.lchmod(path_, stat.S_IWRITE) 
     os.remove(path_) 


def force_remove_file_or_symlink(path_): 
    try: 
     os.remove(path_) 
    except OSError: 
     os.lchmod(path_, stat.S_IWRITE) 
     os.remove(path_) 


# Code from shutil.rmtree() 
def is_regular_dir(path_): 
    try: 
     mode = os.lstat(path_).st_mode 
    except os.error: 
     mode = 0 
    return stat.S_ISDIR(mode) 


def clear_dir(path_): 
    if is_regular_dir(path_): 
     # Given path is a directory, clear its content 
     for name in os.listdir(path_): 
      fullpath = os.path.join(path_, name) 
      if is_regular_dir(fullpath): 
       shutil.rmtree(fullpath, onerror=_remove_readonly) 
      else: 
       force_remove_file_or_symlink(fullpath) 
    else: 
     # Given path is a file or a symlink. 
     # Raise an exception here to avoid accidentally clearing the content 
     # of a symbolic linked directory. 
     raise OSError("Cannot call clear_dir() on a symbolic link") 
-3

Diese den Trick tun sollte nur das OS-Modul zur Liste und entfernen Sie dann!

import os 
DIR = os.list('Folder') 
for i in range(len(DIR)): 
    os.remove('Folder'+chr(92)+i) 

Arbeitete für mich, irgendwelche Probleme lassen Sie mich wissen!

0

Antwort für eine begrenzte, spezifische Situation: vorausgesetzt, Sie die Dateien löschen möchten, während die Unterordner Baum konserviert, könnten Sie einen rekursiven Algorithmus verwenden:

import os 

def recursively_remove_files(f): 
    if os.path.isfile(f): 
     os.unlink(f) 
    elif os.path.isdir(f): 
     map(recursively_remove_files, [os.path.join(f,fi) for fi in os.listdir(f)]) 

recursively_remove_files(my_directory) 

Vielleicht etwas off-topic, aber ich denke, dass viele würde es nützlich finden

1

Ich löste das Fehlerproblem mit rmtree makedirs, indem ich time.sleep() dazwischen hinzufüge.

if os.path.isdir(folder_location): 
    shutil.rmtree(folder_location) 

time.sleep(.5) 

os.makedirs(folder_location, 0o777) 
Verwandte Themen