Odpowiedzi:
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:
tymi odczytami W0703: Catching too general exception Exception
. Czy jest jakiś konkretniejszy wyjątek do złapania, czy powinienem go zignorować?
Możesz po prostu to zrobić:
import os
import glob
files = glob.glob('/YOUR/PATH/*')
for f in files:
os.remove(f)
Oczywiście możesz użyć innego filtra w swojej ścieżce, na przykład: /YOU/PATH/*.txt do usunięcia wszystkich plików tekstowych z katalogu.
*
nie będzie wyświetlał ukrytych plików, powinniśmy również dodaćglob.glob('path/.*)
import sh; sh.rm(files)
import sh; sh.rm(files)
wygląda ładniej, możesz napotkać problemy, jeśli w katalogu jest więcej niż 1024 pliki.
Możesz usunąć sam folder, a także całą jego zawartość, używając shutil.rmtree
:
import shutil
shutil.rmtree('/path/to/folder')
shutil.rmtree(path, ignore_errors=False, onerror=None)
Usuń całe drzewo katalogów; ścieżka musi wskazywać na katalog (ale nie symboliczne łącze do katalogu). Jeśli parametr ignore_errors ma wartość true, błędy wynikające z nieudanych operacji usuwania zostaną zignorowane; w przypadku fałszu lub pominięcia, takie błędy są obsługiwane przez wywołanie procedury obsługi określonej przez onerror lub, jeśli zostanie pominięte, zgłoszą wyjątek.
rmtree
. Jakos.makedirs(dir)
OSError: [Errno 16] Device or resource busy
Rozwijając odpowiedź mhawke, właśnie to zaimplementowałem. Usuwa całą zawartość folderu, ale nie sam folder. Testowany w systemie Linux z plikami, folderami i dowiązaniami symbolicznymi powinien również działać w systemie 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
służy do podziału katalogów na pliki, które muszą być obsługiwane w inny sposób. Możesz także użyć os.listdir
, ale musisz ręcznie sprawdzić, czy każdy wpis jest katalogiem lub plikiem.
os.walk
tutaj się nie powtórzy, ponieważ zwraca generator, tylko rekurencyjnie przegląda podkatalogi, gdy próbujesz go rozwinąć, a do czasu pierwszej iteracji tej pętli nie ma podkatalogów pozostawiony do obejrzenia. Zasadniczo os.walk
jest tutaj używany jako alternatywny sposób odróżnienia folderów najwyższego poziomu od plików najwyższego poziomu; rekurencja nie jest używana i nie ponosimy za nią kosztów wydajności. Jest to jednak ekscentryczne i zgadzam się, że proponowane przez ciebie podejście jest lepsze po prostu dlatego, że jest bardziej wyraźne i czytelne.
Używanie rmtree
i odtwarzanie folderu może działać, ale podczas usuwania i natychmiastowego odtwarzania folderów na dyskach sieciowych napotkałem błędy.
Proponowane rozwiązanie wykorzystujące walk nie działa, ponieważ służy rmtree
do usuwania folderów, a następnie może próbować użyć os.unlink
plików wcześniej znajdujących się w tych folderach. To powoduje błąd.
Opublikowane glob
rozwiązanie będzie również próbowało usunąć niepuste foldery, powodując błędy.
Sugeruję użycie:
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()
powróci False
(ponieważ następuje dowiązanie symboliczne), a w końcu wywołasz shutil.rmtree()
dowiązanie symboliczne, które się podniesie OSError("Cannot call rmtree on a symbolic link")
.
islink
sprawdzenia tutaj, aby poprawnie obsługiwać dowiązania symboliczne do katalogów. Dodałem taki czek do zaakceptowanej odpowiedzi.
To:
Kod:
for filename in os.listdir(dirpath):
filepath = os.path.join(dirpath, filename)
try:
shutil.rmtree(filepath)
except OSError:
os.remove(filepath)
Jak wiele innych odpowiedzi, nie próbuje to dostosowywać uprawnień, aby umożliwić usuwanie plików / katalogów.
Jako 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)) ) )
Bardziej niezawodnym rozwiązaniem uwzględniającym również pliki i katalogi byłoby (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
w list
rzeczywiście iteracyjne. Zobacz http://stackoverflow.com/questions/1303347/getting-a-map-to-return-a-list-in-python-3-x
Uwagi: na wypadek, gdyby ktoś głosował za moją odpowiedzią, muszę coś wyjaśnić.
shutil.rmtree()
można go użyć do usunięcia drzewa katalogów. Użyłem go wiele razy w swoich własnych projektach. Musisz jednak zdać sobie sprawę, że sam katalog również zostanie usuniętyshutil.rmtree()
. Chociaż może to być akceptowalne dla niektórych, nie jest to poprawna odpowiedź na usunięcie zawartości folderu (bez skutków ubocznych) .shutil.rmtree()
i odbudowuje się za pomocą os.mkdir()
. Zamiast tego otrzymasz pusty katalog z domyślnymi (odziedziczonymi) bitami właściciela i trybu. Chociaż możesz mieć uprawnienia do usuwania zawartości, a nawet katalogu, możesz nie być w stanie przywrócić pierwotnego właściciela i bitów trybu w katalogu (np. Nie jesteś superużytkownikiem).Oto długie i brzydkie, ale niezawodne i wydajne rozwiązanie.
Rozwiązuje kilka problemów, które nie zostały rozwiązane przez innych użytkowników:
shutil.rmtree()
łącza symbolicznego (które przejdzieos.path.isdir()
test, jeśli zostanie dowiązany do katalogu; nawet wynik os.walk()
zawiera również dowiązania symboliczne).Oto kod (jedyną przydatną funkcją jest 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
w przeciwieństwie do rm
narzędzia, z przyjemnością usuwa pliki tylko do odczytu, o ile jesteś ich właścicielem. Tymczasem jeśli jest to plik, którego nie posiadasz, do którego masz dostęp tylko do odczytu, nie możesz go usunąć ani zmienić jego uprawnień. Nie znam żadnej sytuacji w żadnym systemie, w której nie można usunąć pliku tylko do odczytu, os.remove
ale można zmienić jego uprawnienia. Ponadto używasz lchmod
, który nie istnieje na moim komputerze Mac, ani w systemie Windows zgodnie z jego dokumentacją. Dla jakiej platformy przeznaczony jest ten kod ?!
Dziwi mnie, że nikt nie wspominał o niesamowitym pathlib
wykonywaniu tej pracy.
Jeśli chcesz tylko usunąć pliki z katalogu, może to być oneliner
from pathlib import Path
[f.unlink() for f in Path("/path/to/folder").glob("*") if f.is_file()]
Aby rekurencyjnie usunąć katalogi, możesz napisać coś takiego:
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()
zamiast .glob(...)
powinien również działać.
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]
Wcześniejszy komentarz wspomina także o użyciu os.scandir w Python 3.5+. Na przykład:
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()
nie jest prawidłowym sposobem na odróżnienie zwykłego katalogu od dowiązania symbolicznego. Wywołanie shutil.rmtree()
dowiązania symbolicznego spowoduje OSError
wyjątek.
Rozwiązałem problem w ten sposób:
import shutil
import os
shutil.rmtree(dirpath)
os.mkdir(dirpath)
Jeszcze inne rozwiązanie:
import sh
sh.rm(sh.glob('/path/to/folder/*'))
sh
nie jest częścią standardowej biblioteki i wymaga instalacji z PyPI, zanim będziesz mógł z niej korzystać. Ponadto, ponieważ faktycznie wywołuje rm
to podproces, nie będzie działać w systemie Windows, gdzie rm
nie istnieje. Zgłasza także wyjątek, jeśli folder zawiera jakieś podkatalogi.
Wiem, że to stary wątek, ale znalazłem coś ciekawego na oficjalnej stronie Pythona. Wystarczy udostępnić kolejny pomysł na usunięcie całej zawartości katalogu. Ponieważ mam pewne problemy z autoryzacją podczas korzystania z shutil.rmtree () i nie chcę usuwać katalogu i odtwarzać go ponownie. Oryginalny adres to http://docs.python.org/2/library/os.html#os.walk . Mam nadzieję, że może komuś pomóc.
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))
Aby usunąć wszystkie pliki w katalogu oraz jego podkatalogach, bez usuwania samych folderów, po prostu wykonaj następujące czynności:
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))
Jeśli używasz systemu * nix, dlaczego nie skorzystać z polecenia systemowego?
import os
path = 'folder/to/clean'
os.system('rm -rf %s/*' % path)
Musiałem usunąć pliki z 3 oddzielnych folderów w jednym katalogu nadrzędnym:
directory
folderA
file1
folderB
file2
folderC
file3
Ten prosty kod załatwił sprawę: (Jestem na Uniksie)
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)
Mam nadzieję że to pomoże.
Odpowiedz na ograniczoną, konkretną sytuację: zakładając, że chcesz usunąć pliki podczas utrzymywania drzewa podfolderów, możesz użyć algorytmu rekurencyjnego:
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)
Może nieco nie na temat, ale myślę, że wielu uznałoby to za przydatne
os.walk
w sposób pokazany na stackoverflow.com/a/54889532/1709587 jest być może lepszym sposobem na usunięcie wszystkich plików przy jednoczesnym zachowaniu nienaruszonej struktury katalogów.
Użyj metody poniżej, aby usunąć zawartość katalogu, a nie sam katalog:
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)
najprostszy sposób na usunięcie wszystkich plików w folderze / usunięcie wszystkich plików
import os
files = os.listdir(yourFilePath)
for f in files:
os.remove(yourFilePath + f)
os.system('rm -rf folder')