Risposte:
import os, shutil
folder = '/path/to/folder'
for filename in os.listdir(folder):
file_path = os.path.join(folder, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print('Failed to delete %s. Reason: %s' % (file_path, e))
except Exception as e:
letture W0703: Catching too general exception Exception
. Esiste un'eccezione più specifica da rilevare o devo ignorarla?
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.
*
non elencherà i file nascosti, dovremmo anche aggiungereglob.glob('path/.*)
import sh; sh.rm(files)
import sh; sh.rm(files)
se sembra più bello, ci sono problemi se ci sono più di 1024 file nella directory.
Puoi eliminare la cartella stessa, così come tutto il suo contenuto, usando shutil.rmtree
:
import shutil
shutil.rmtree('/path/to/folder')
shutil.rmtree(path, ignore_errors=False, onerror=None)
Elimina un intero albero di directory; il percorso deve puntare a una directory (ma non un collegamento simbolico a una directory). Se ignore_errors è true, gli errori risultanti da rimozioni non riuscite verranno ignorati; se falsi o omessi, tali errori vengono gestiti chiamando un gestore specificato da onerror o, se viene omesso, generano un'eccezione.
rmtree
. Comeos.makedirs(dir)
OSError: [Errno 16] Device or resource busy
Espandendo la risposta di mhawke questo è ciò 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))
walk
viene utilizzato per dividere dirs vs file, che devono essere gestiti in modo diverso. Potresti anche usare os.listdir
, ma dovresti controllare se ogni voce è una directory o un file manualmente.
os.walk
non verrà ripreso qui, perché restituisce un generatore che esamina ricorsivamente le sottodirectory solo quando provi ad avanzare, e quando hai eseguito la prima iterazione di questo ciclo, non ci sono sottodirectory lasciato a guardare. In sostanza, os.walk
viene usato qui solo come un modo alternativo di distinguere le cartelle di livello superiore dai file di livello superiore; la ricorsione non viene utilizzata e non paghiamo alcun costo di performance. È eccentrico, tuttavia, e concordo sul fatto che l'approccio che suggerisci è migliore semplicemente perché è più esplicito e leggibile.
L'uso rmtree
e la ricreazione della cartella potrebbe funzionare, ma ho riscontrato 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
i file che erano in precedenza in tali cartelle. Questo provoca un errore.
La glob
soluzione pubblicata tenterà inoltre 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) or os.path.islink(file_object_path):
os.unlink(file_object_path)
else:
shutil.rmtree(file_object_path)
os.path.isfile()
tornerà False
(perché segue i link simbolici) e finirai per chiamare shutil.rmtree()
un link simbolico, che aumenterà OSError("Cannot call rmtree on a symbolic link")
.
islink
controllo qui per gestire correttamente i collegamenti simbolici alle directory. Ho aggiunto un tale assegno alla risposta accettata.
Questo:
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)) )
map( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) )
list(map(os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir))))
map
in list
realmente iterare. Vedi http://stackoverflow.com/questions/1303347/getting-a-map-to-return-a-list-in-python-3-x
Note: nel caso in cui qualcuno abbia votato la mia risposta, ho qualcosa da spiegare qui.
shutil.rmtree()
potrebbe essere usato per cancellare un albero di directory. L'ho usato molte volte nei miei progetti. Ma devi capire che anche la directory stessa verrà eliminata dashutil.rmtree()
. Anche se questo potrebbe essere accettabile per alcuni, non è una risposta valida per eliminare il contenuto di una cartella (senza effetti collaterali) .shutil.rmtree()
e lo ricostruisci con os.mkdir()
. E otterrai invece una directory vuota con i proprietari (ereditati) predefiniti e bit di 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 es. Non sei un superutente).Ecco una soluzione lunga e brutta, ma affidabile ed efficiente.
Risolve alcuni problemi che non vengono risolti dagli altri risponditori:
shutil.rmtree()
un collegamento simbolico (che supererà il os.path.isdir()
test se si collega a una directory; anche il risultato dios.walk()
contiene anche directory simboliche collegate).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")
os.remove
, a differenza del rm
programma di utilità, è felice di cancellare i file di sola lettura finché li si possiede. Nel frattempo, se si tratta di un file di cui non si possiede l'accesso di sola lettura, non è possibile eliminarlo o modificarne le autorizzazioni. Non conosco alcuna situazione su nessun sistema in cui non saresti in grado di eliminare un file di sola lettura con la os.remove
possibilità di modificarne le autorizzazioni. Inoltre, usi lchmod
, che non esiste sul mio Mac, né su Windows secondo i suoi documenti. A quale piattaforma è destinato questo codice ?!
Sono sorpreso che nessuno abbia menzionato il fantastico pathlib
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)
.iterdir()
invece di .glob(...)
dovrebbe funzionare anche.
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+. Per 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)
os.path.isdir()
non è un modo valido per distinguere tra una directory normale e un collegamento simbolico. La chiamata shutil.rmtree()
a un collegamento simbolico genererà OSError
un'eccezione.
Potrebbe essere meglio usarlo 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 di come utilizzare os.walk()
per rimuovere ricorsivamente una directory qui e suggerimenti su come adattarla alle circostanze.
Ho usato per risolvere il problema in questo modo:
import shutil
import os
shutil.rmtree(dirpath)
os.mkdir(dirpath)
Ancora un'altra soluzione:
import sh
sh.rm(sh.glob('/path/to/folder/*'))
sh
non fa parte della libreria standard e deve essere installato da PyPI prima di poterlo utilizzare. Inoltre, poiché in realtà questo invoca rm
in un sottoprocesso, non funzionerà su Windows dove rm
non esiste. Inoltre genererà un'eccezione se la cartella contiene delle sottodirectory.
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))
Per eliminare tutti i file all'interno della directory e le relative sottodirectory, senza rimuovere le cartelle stesse, è sufficiente:
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))
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)
Ho dovuto rimuovere i file da 3 cartelle separate all'interno di un'unica directory padre:
directory
folderA
file1
folderB
file2
folderC
file3
Questo semplice codice mi ha aiutato: (Sono su Unix)
import os
import glob
folders = glob.glob('./path/to/parentdir/*')
for fo in folders:
file = glob.glob(f'{fo}/*')
for f in file:
os.remove(f)
Spero che sia di aiuto.
Rispondi per una situazione specifica limitata: supponendo che tu voglia eliminare i file mentre mantieni l'albero delle sottocartelle, potresti usare un algoritmo ricorsivo:
import os
def recursively_remove_files(f):
if os.path.isfile(f):
os.unlink(f)
elif os.path.isdir(f):
for fi in os.listdir(f):
recursively_remove_files(os.path.join(f, fi))
recursively_remove_files(my_directory)
Forse leggermente fuori tema, ma penso che molti lo troverebbero utile
os.walk
nel modo mostrato su stackoverflow.com/a/54889532/1709587 è forse un modo migliore di eliminare tutti i file lasciando intatta la struttura delle directory.
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)
il modo più semplice per eliminare tutti i file in una cartella / rimuovere tutti i file
import os
files = os.listdir(yourFilePath)
for f in files:
os.remove(yourFilePath + f)
os.system('rm -rf folder')