Domanda

Come posso eliminare il contenuto di una cartella locale in Python?

Il progetto attuale è per Windows, ma vorrei vedere anche * nix.

È stato utile?

Soluzione

Aggiornato per eliminare solo i file e per utilizzare il metodo os.path.join () suggerito nei commenti. Se si desidera rimuovere anche le sottodirectory, rimuovere il commento dall'istruzione elif .

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)

Altri suggerimenti

Prova il modulo shutil

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

Descrizione: shutil.rmtree (path, ignore_errors = False, onerror = None)

     

Docstring: elimina ricorsivamente a   albero delle directory.

     

Se è impostato ignore_errors , gli errori sono   ignorato; altrimenti, se è impostato onerror ,   viene chiamato per gestire l'errore con   argomenti (func, path, exc_info) dove    func è os.listdir , os.remove o    os.rmdir ; il percorso è l'argomento   funzione che ha causato il fallimento; e    exc_info è una tupla restituita da    sys.exc_info () . Se ignore_errors è   false e onerror è None , an   viene sollevata un'eccezione.

Nota importante: tieni presente che shutil.rmtree () non cancella solo il contenuto della cartella di destinazione. Elimina anche la cartella stessa.

Puoi semplicemente farlo:

import os
import glob

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

Ovviamente puoi usare un altro filtro nel tuo percorso, ad esempio: /YOU/PATH/*.txt per rimuovere tutti i file di testo in una directory.

Ampliare la risposta di mhawke è questo che ho implementato. Rimuove tutto il contenuto di una cartella ma non la cartella stessa. Testato su Linux con file, cartelle e collegamenti simbolici, dovrebbe funzionare anche su Windows.

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))

L'uso di rmtree e ricreare la cartella potrebbe funzionare, ma ho riscontrato degli errori durante l'eliminazione e la ricostruzione immediata delle cartelle sulle unità di rete.

La soluzione proposta utilizzando walk non funziona in quanto utilizza rmtree per rimuovere le cartelle e quindi può tentare di utilizzare os.unlink sui file che erano precedentemente in quelle cartelle . Ciò provoca un errore.

La soluzione glob pubblicata tenterà anche di eliminare cartelle non vuote, causando errori.

Ti suggerisco di usare:

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)

Questa è l'unica risposta finora, che:

  • rimuove tutti i collegamenti simbolici
    • link non funzionanti
    • collegamenti alle directory
    • collegamenti a file
  • rimuove le sottodirectory
  • non rimuove la directory principale

Codice:

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

Come molte altre risposte, questo non tenta di regolare le autorizzazioni per consentire la rimozione di file / directory.

Come 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)) ) )

Una soluzione più solida che tiene conto anche di file e directory (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)) )

Note: nel caso in cui qualcuno abbia votato la mia risposta, ho qualcosa da spiegare qui.

  1. A tutti piacciono le risposte brevi e semplici. Tuttavia, a volte la realtà non è così semplice.
  2. Torna alla mia risposta. So che shutil.rmtree () potrebbe essere usato per cancellare un albero di directory. L'ho usato molte volte nei miei progetti. Ma devi capire che la directory stessa verrà eliminata anche da shutil.rmtree() . Anche se questo potrebbe essere accettabile per alcuni, non è una risposta valida per eliminare il contenuto di una cartella (senza effetti collaterali) .
  3. Ti mostrerò un esempio degli effetti collaterali. Supponiamo di avere una directory con personalizzato e bit di modalità, in cui ci sono molti contenuti. Quindi lo elimini con shutil.rmtree () e lo ricostruisci con os.mkdir () . E otterrai invece una directory vuota con predefinito (ereditato) bit di proprietario e modalità. Mentre potresti avere il privilegio di eliminare il contenuto e persino la directory, potresti non essere in grado di ripristinare il proprietario originale e i bit della modalità nella directory (ad esempio, non sei un superutente).
  4. Infine, sii paziente e leggi il codice . È lungo e brutto (in vista), ma dimostrato di essere affidabile ed efficiente (in uso).

Ecco una soluzione lunga e brutta, ma affidabile ed efficiente.

Risolve alcuni problemi che non vengono risolti dagli altri risponditori:

  • Gestisce correttamente i collegamenti simbolici, incluso non chiamare shutil.rmtree () su un collegamento simbolico (che supererà il test os.path.isdir () se si collega a una directory; anche il risultato di os.walk () contiene anche directory simboliche collegate).
  • Gestisce bene i file di sola lettura.

Ecco il codice (l'unica funzione utile è 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")
import os
import shutil

# Gather directory contents
contents = [os.path.join(target_dir, i) for i in os.listdir(target_dir)]

# Iterate and remove each item in the appropriate manner
[os.remove(i) if os.path.isfile(i) or os.path.islink(i) else shutil.rmtree(i) for i in contents]

Un commento precedente menziona anche l'uso di os.scandir in Python 3.5+. Ad esempio:

import os
import shutil

with os.scandir(target_dir) as entries:
    for entry in entries:
        if entry.is_file() or entry.is_symlink():
            os.remove(entry.path)
        elif entry.is_dir():
            shutil.rmtree(entry.path)

Potrebbe essere meglio usare os.walk () per questo.

os.listdir () non distingue i file dalle directory e ti metterai rapidamente nei guai nel tentativo di scollegarli. C'è un buon esempio dell'uso di os.walk () per rimuovere ricorsivamente una directory qui e suggerimenti su come adattarlo alle tue circostanze.

In passato risolvo il problema:

import shutil
import os

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

So che è un vecchio thread ma ho trovato qualcosa di interessante dal sito ufficiale di Python. Solo per condividere un'altra idea per la rimozione di tutti i contenuti in una directory. Perché ho alcuni problemi di autorizzazione quando uso shutil.rmtree () e non voglio rimuovere la directory e ricrearla. L'indirizzo originale è http://docs.python.org/2/library /os.html#os.walk . Spero che possa aiutare qualcuno.

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))

Ancora un'altra soluzione:

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

Se si utilizza un sistema * nix, perché non sfruttare il comando di sistema?

import os
path = 'folder/to/clean'
os.system('rm -rf %s/*' % path)

Sono sorpreso che nessuno abbia menzionato il fantastico pathlib per fare questo lavoro.

Se vuoi solo rimuovere i file in una directory, può essere un oneliner

from pathlib import Path

[f.unlink() for f in Path("/path/to/folder").glob("*") if f.is_file()] 

Per rimuovere ricorsivamente anche le directory puoi scrivere qualcosa del genere:

from pathlib import Path
from shutil import rmtree

for path in Path("/path/to/folder").glob("**/*"):
    if path.is_file():
        path.unlink()
    elif path.is_dir():
        rmtree(path)

Ho risolto il problema con rmtree makedirs aggiungendo time.sleep () tra:

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

time.sleep(.5)

os.makedirs(folder_location, 0o777)

Risposta per una situazione specifica limitata: supponendo di voler eliminare i file mentre si mantiene l'albero delle sottocartelle, è possibile utilizzare un algoritmo ricorsivo:

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)

Forse leggermente fuori tema, ma penso che molti lo troverebbero utile

Supponendo che temp_dir venga eliminato, un comando a riga singola che utilizza os sarebbe:

_ = [os.remove(os.path.join(save_dir,i)) for i in os.listdir(temp_dir)]

Nota: questa è solo una riga per l'eliminazione dei file "Non elimina le directory.

Spero che questo aiuti. Grazie.

Utilizzare il metodo seguente per rimuovere il contenuto di una directory, non la directory stessa:

import os
import shutil

def remove_contents(path):
    for c in os.listdir(path):
        full_path = os.path.join(path, c)
        if os.path.isfile(full_path):
            os.remove(full_path)
        else:
            shutil.rmtree(full_path)

Fallo semplicemente. Questo eliminerà tutti i file all'interno della directory e anche dalle sottodirectory. Senza danneggiare alcuna cartella / directory. Funziona bene su Ubuntu senza errori.

import os
mypath = "my_folder" #Enter your path here
for root, dirs, files in os.walk(mypath):
    for file in files:
        os.remove(os.path.join(root, file))

Questo dovrebbe fare il trucco semplicemente usando il modulo OS per elencare e quindi rimuovere!

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

Ha funzionato per me, qualsiasi problema fammi sapere!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top