Se você estiver trabalhando com um diretório muito grande, principalmente um diretório de rede no Windows, e conseguir controlar o ambiente em que esse programa é executado, pode valer a pena usar a função "os.scandir (pasta)" do Py3.5 em vez de listdir. A sintaxe é bem diferente depois disso, mas bastante simples de implementar; feliz em publicá-lo, se outros quiserem.
22716 Michael Jackson Cuthbert #
Estou recebendo um aviso de pylint com except Exception as e:isso W0703: Catching too general exception Exception. Existe uma exceção mais específica para capturar ou devo ignorá-la?
John Hany
7
@ JohnHany, acredito que você quer pegar o OSError.
MikeB
246
Você pode simplesmente fazer isso:
import os
import glob
files = glob.glob('/YOUR/PATH/*')for f in files:
os.remove(f)
Obviamente, você pode usar outro filtro no caminho, por exemplo: /YOU/PATH/*.txt para remover todos os arquivos de texto em um diretório.
Exclua uma árvore de diretórios inteira; O caminho deve apontar para um diretório (mas não um link simbólico para um diretório). Se ignore_errors for verdadeiro, os erros resultantes de falhas na remoção serão ignorados; se falso ou omitido, esses erros são tratados chamando um manipulador especificado por onerror ou, se isso for omitido, eles geram uma exceção.
Isso não apenas excluirá o conteúdo, mas também a própria pasta. Eu não acho que é o que a pergunta faz.
Iker Jimenez
3
Eu acho que é uma boa resposta. Por que você não exclui o conteúdo e a pasta e refaz a pasta?
Cssndrx 6/07
42
Porque o novo diretório e o antigo não serão os mesmos. Portanto, se um programa estiver no diretório, aguardando as coisas, ele terá o tapete retirado dele.
Mike Cooper
30
Apenas recrie o diretório depois rmtree. Comoos.makedirs(dir)
Iulius Curt
3
@IuliusCurt não, eu tenho um diretório montado no ram que eu preciso esvaziar e, infelizmente, não posso simplesmente excluir e depois recriá-lo:OSError: [Errno 16] Device or resource busy
Arnaud P
80
Expandir a resposta de mhawke é isso que eu implementei. Remove todo o conteúdo de uma pasta, mas não a própria pasta. Testado no Linux com arquivos, pastas e links simbólicos, também deve funcionar no 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))
Por que 'andar' e não apenas listar o conteúdo da pasta?
Don
2
Esta é a resposta correta se você deseja excluir diretórios também. walké usado para dividir diretórios x arquivos, que devem ser tratados de maneira diferente. Você também pode usar os.listdir, mas precisará verificar se cada entrada é um diretório ou arquivo manualmente.
Dkamins 16/03/12
7
Isso está próximo, mas os.walk e shutil.rmtree são recursivos. o os.walk é desnecessário, pois você só precisa que os arquivos e diretórios no nível superior dentro do diretório sejam limpos. Basta usar uma instrução if nos elementos do os.listdir para ver se cada um é um arquivo ou diretório. Em seguida, use remover / desvincular e rmtree, respectivamente.
Matthew Alpert
1
@MatthewAlpert Note, no entanto, que os.walknão será repetido aqui, porque retorna um gerador que apenas recursivamente examina subdiretórios quando você tenta avançar e, quando você faz sua primeira iteração desse loop, não há subdiretórios esquerda para olhar. Em essência, os.walkestá apenas sendo usado aqui como uma maneira alternativa de distinguir pastas de nível superior dos arquivos de nível superior; a recursão não está sendo usada e não pagamos nenhum custo por desempenho. É excêntrico, no entanto, e concordo que a abordagem que você sugere é melhor simplesmente porque é mais explícita e legível.
Mark Amery
47
Usar rmtreee recriar a pasta pode funcionar, mas eu encontrei erros ao excluir e recriar imediatamente as pastas nas unidades de rede.
A solução proposta usando walk não funciona da mesma maneira que rmtreeremove pastas e, em seguida, pode tentar usar os.unlinkos arquivos que estavam anteriormente nessas pastas. Isso causa um erro.
A globsolução publicada também tentará excluir pastas não vazias, causando erros.
Sua solução também gerará um erro se houver um link simbólico para outro diretório.
Blueicefield
@Blueicefield - Você pode fornecer um exemplo. Eu testei no linux usando um arquivo e uma pasta com link simbólico e ainda não consegui causar um erro.
jgoeders
@jgoeders - Se houver um link simbólico para um diretório, os.path.isfile()ele retornará False(porque segue links simbólicos) e você acabará chamando shutil.rmtree()um link simbólico, o que aumentará OSError("Cannot call rmtree on a symbolic link").
Rockallite 19/07/2014
1
@Rockallite fixo por cheque para IsLink
kevinf
1
Além disso: @kevinf está correto ao apontar a necessidade de uma islinkverificação aqui para manipular links simbólicos para diretórios corretamente. Eu adicionei essa verificação à resposta aceita.
Mark Amery
20
Este:
remove todos os links simbólicos
links mortos
links para diretórios
links para arquivos
remove subdiretórios
não remove o diretório pai
Código:
for filename in os.listdir(dirpath):
filepath = os.path.join(dirpath, filename)try:
shutil.rmtree(filepath)exceptOSError:
os.remove(filepath)
Como muitas outras respostas, isso não tenta ajustar as permissões para permitir a remoção de arquivos / diretórios.
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))))
Uma solução mais robusta que contabilize arquivos e diretórios também seria (2.7):
def rm(f):if os.path.isdir(f):return os.rmdir(f)if os.path.isfile(f):return os.unlink(f)raiseTypeError,'must be either file or directory'
map( rm,(os.path.join( mydir,f)for f in os.listdir(mydir)))
para grandes operações, utilizando o gerador pode ser fraccionada mais eficientemap( os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir)) )
user25064
realmente tentando usar isso, percebeu que o objeto do mapa deve ser iterado assim uma chamada à lista (ou algo que vai iterate) é necessária comolist(map(os.unlink, (os.path.join( mydir,f) for f in os.listdir(mydir))))
user25064
O primeiro incluído na resposta, o segundo não faz sentido para mim. Por que você deve iterar sobre uma função mapeada para uma iterável? O mapa faz isso.
Este definitivamente não funcionará se 'mydir' contém pelo menos uma pasta, como obras Desvincular para arquivos somente ...
kupsef
14
Observações: caso alguém rejeite minha resposta, tenho algo a explicar aqui.
Todo mundo gosta de respostas curtas e simples. No entanto, às vezes a realidade não é tão simples.
De volta à minha resposta. Eu sei que shutil.rmtree()poderia ser usado para excluir uma árvore de diretórios. Eu o usei muitas vezes em meus próprios projetos. Mas você deve perceber que o próprio diretório também será excluído porshutil.rmtree() . Embora isso possa ser aceitável para alguns, não é uma resposta válida para excluir o conteúdo de uma pasta (sem efeitos colaterais) .
Vou mostrar um exemplo dos efeitos colaterais. Suponha que você tenha um diretório com proprietário personalizado e bits de modo, onde há muito conteúdo. Em seguida, você a exclui shutil.rmtree()e a reconstrói com os.mkdir(). E você obterá um diretório vazio com os bits padrão e herdados do proprietário e do modo. Embora você possa ter o privilégio de excluir o conteúdo e até o diretório, talvez não seja possível atrasar o proprietário original e os bits de modo no diretório (por exemplo, você não é um superusuário).
Por fim, seja paciente e leia o código . É longo e feio (à vista), mas provou ser confiável e eficiente (em uso).
Aqui está uma solução longa e feia, mas confiável e eficiente.
Resolve alguns problemas que não são abordados pelos outros respondentes:
Ele lida corretamente com links simbólicos, incluindo a não chamada shutil.rmtree()de um link simbólico (que passará no os.path.isdir()teste se ele vincular a um diretório; até o resultado também os.walk()conterá diretórios simbólicos).
Ele lida bem com arquivos somente leitura.
Aqui está o código (a única função útil é clear_dir()):
import os
import stat
import shutil
# http://stackoverflow.com/questions/1889597/deleting-directory-in-pythondef _remove_readonly(fn, path_, excinfo):# Handle read-only files and directoriesif 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_)exceptOSError:
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 =0return stat.S_ISDIR(mode)def clear_dir(path_):if is_regular_dir(path_):# Given path is a directory, clear its contentfor 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.raiseOSError("Cannot call clear_dir() on a symbolic link")
Não entendo em que contexto alterar o modo de arquivo faz sentido. No meu Mac, os.remove, ao contrário da rmutilidade, tem o prazer de excluir somente leitura arquivos enquanto você possuí-los. Enquanto isso, se é um arquivo do qual você não possui apenas acesso somente leitura, não pode excluí-lo ou alterar suas permissões. Não conheço nenhuma situação em nenhum sistema em que você não os.removeconsiga excluir um arquivo somente leitura e ainda possa alterar suas permissões. Além disso, você usa lchmod, o que não existe no meu Mac, nem no Windows, de acordo com seus documentos. Para que plataforma esse código se destina ?!
Mark Amery
14
Estou surpreso que ninguém tenha mencionado o incrível pathlibpara fazer este trabalho.
Se você deseja apenas remover arquivos em um diretório, pode ser um oneliner
from pathlib importPath[f.unlink()for f inPath("/path/to/folder").glob("*")if f.is_file()]
Para também remover diretórios recursivamente, você pode escrever algo como isto:
from pathlib importPathfrom shutil import rmtree
for path inPath("/path/to/folder").glob("**/*"):if path.is_file():
path.unlink()elif path.is_dir():
rmtree(path)
.iterdir()em vez de .glob(...)também deve funcionar.
S. Kirby
12
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]
Um comentário anterior também menciona o uso de os.scandir no Python 3.5+. Por exemplo:
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()não é uma maneira válida de distinguir entre um diretório regular e um link simbólico. Chamar shutil.rmtree()um link simbólico gerará uma OSErrorexceção.
Rockallite 19/07/2014
@Rockallite Thanks. Você está certo. Eu atualizei o exemplo.
Jacob Wan
8
Você pode estar melhor usando os.walk()isso.
os.listdir()não distingue arquivos de diretórios e você terá problemas para tentar desvinculá-los rapidamente. Há um bom exemplo de os.walk()como remover um diretório recursivamente aqui e dicas de como adaptá-lo às suas circunstâncias.
Isso tem semântica radicalmente diferente do que a pergunta faz e não deve ser considerada uma resposta válida.
Fatuhoku 26/09
1
Com relação a isso, acho que "Excluir o conteúdo da pasta local" não envolve remover a própria pasta. O mesmo problema que esta resposta , exceto que recebemos muitas votações!
fatuhoku 26/09
3
É como responder à pergunta "Como faço para uma função retornar o número 1 no Python?" com def return_a_one (): launch_some_nukes () return 1
fatuhoku 26/09
2
É claro que a semântica é diferente: mas você também pode considerá-la como outra maneira de analisar o problema. Esta solução é perfeitamente válida, pois resolve o problema. Há uma diferença no exemplo do seu 'launch_some_nukes': 1. A solução é mais curta e fácil do que a aceita e, ao contrário da resposta citada, é válida. 2. o equivalente 'launch_some_nukes', neste caso, está excluindo e recriando uma pasta. A diferença entre a velha ea nova pasta é apenas o número inode (provavelmente irrelevante para a OP)
ProfHase85
2
É bastante demolição do arranha-céus e reconstruir um exatamente o mesmo tamanho;)
Observe que isso shnão faz parte da biblioteca padrão e precisa ser instalado a partir do PyPI para que você possa usá-lo. Além disso, como isso realmente é chamado rmem um subprocesso, não funcionará no Windows onde rmnão existe. Isso também gerará uma exceção se a pasta contiver subdiretórios.
Mark Amery
5
Eu sei que é um tópico antigo, mas encontrei algo interessante no site oficial do python. Apenas para compartilhar outra ideia para remover todo o conteúdo de um diretório. Porque tenho alguns problemas de autorização ao usar shutil.rmtree () e não quero remover o diretório e recriá-lo. O endereço original é http://docs.python.org/2/library/os.html#os.walk . Espero que possa ajudar alguém.
def emptydir(top):if(top =='/'or top =="\\"):returnelse: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))
Resposta para uma situação específica e limitada: supondo que você queira excluir os arquivos enquanto mantém a árvore de subpastas, você pode usar um algoritmo recursivo:
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)
Talvez um pouco fora de tópico, mas acho que muitos achariam útil
Usar os.walkda maneira mostrada em stackoverflow.com/a/54889532/1709587 talvez seja uma maneira melhor de excluir todos os arquivos enquanto mantém intacta a estrutura de diretórios.
Mark Amery
-1
Supondo temp_dirque seja excluído, um comando de linha única usando osseria:
_ =[os.remove(os.path.join(save_dir,i))for i in os.listdir(temp_dir)]
Nota: Este é apenas um alinhador para excluir arquivos 'Não exclui diretórios.
obrigado Amir, estou à procura de uma solução que encontra uma determinada pasta em todos os subdiretórios de um diretório raiz e remove o conteúdo dessa pasta
FabioSpaghetti
Isso não adiciona nada de novo que ainda não foi mostrado na resposta aceita anos antes de você postar isso.
Mark Amery
-1
a maneira mais fácil de excluir todos os arquivos em uma pasta / remover todos os arquivos
import os
files = os.listdir(yourFilePath)for f in files:
os.remove(yourFilePath + f)
os.system('rm -rf folder')
Respostas:
fonte
except Exception as e:
issoW0703: Catching too general exception Exception
. Existe uma exceção mais específica para capturar ou devo ignorá-la?Você pode simplesmente fazer isso:
Obviamente, você pode usar outro filtro no caminho, por exemplo: /YOU/PATH/*.txt para remover todos os arquivos de texto em um diretório.
fonte
*
não lista oculta arquivos, devemos acrescentar tambémglob.glob('path/.*)
import sh; sh.rm(files)
import sh; sh.rm(files)
pareça mais bonito, você terá problemas se houver mais de 1024 arquivos no diretório.Você pode excluir a própria pasta, bem como todo o seu conteúdo, usando
shutil.rmtree
:fonte
rmtree
. Comoos.makedirs(dir)
OSError: [Errno 16] Device or resource busy
Expandir a resposta de mhawke é isso que eu implementei. Remove todo o conteúdo de uma pasta, mas não a própria pasta. Testado no Linux com arquivos, pastas e links simbólicos, também deve funcionar no Windows.
fonte
walk
é usado para dividir diretórios x arquivos, que devem ser tratados de maneira diferente. Você também pode usaros.listdir
, mas precisará verificar se cada entrada é um diretório ou arquivo manualmente.os.walk
não será repetido aqui, porque retorna um gerador que apenas recursivamente examina subdiretórios quando você tenta avançar e, quando você faz sua primeira iteração desse loop, não há subdiretórios esquerda para olhar. Em essência,os.walk
está apenas sendo usado aqui como uma maneira alternativa de distinguir pastas de nível superior dos arquivos de nível superior; a recursão não está sendo usada e não pagamos nenhum custo por desempenho. É excêntrico, no entanto, e concordo que a abordagem que você sugere é melhor simplesmente porque é mais explícita e legível.Usar
rmtree
e recriar a pasta pode funcionar, mas eu encontrei erros ao excluir e recriar imediatamente as pastas nas unidades de rede.A solução proposta usando walk não funciona da mesma maneira que
rmtree
remove pastas e, em seguida, pode tentar usaros.unlink
os arquivos que estavam anteriormente nessas pastas. Isso causa um erro.A
glob
solução publicada também tentará excluir pastas não vazias, causando erros.Eu sugiro que você use:
fonte
os.path.isfile()
ele retornaráFalse
(porque segue links simbólicos) e você acabará chamandoshutil.rmtree()
um link simbólico, o que aumentaráOSError("Cannot call rmtree on a symbolic link")
.islink
verificação aqui para manipular links simbólicos para diretórios corretamente. Eu adicionei essa verificação à resposta aceita.Este:
Código:
Como muitas outras respostas, isso não tenta ajustar as permissões para permitir a remoção de arquivos / diretórios.
fonte
Como oneliner:
Uma solução mais robusta que contabilize arquivos e diretórios também seria (2.7):
fonte
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
-selist
para realmente iterar. Veja http://stackoverflow.com/questions/1303347/getting-a-map-to-return-a-list-in-python-3-xObservações: caso alguém rejeite minha resposta, tenho algo a explicar aqui.
shutil.rmtree()
poderia ser usado para excluir uma árvore de diretórios. Eu o usei muitas vezes em meus próprios projetos. Mas você deve perceber que o próprio diretório também será excluído porshutil.rmtree()
. Embora isso possa ser aceitável para alguns, não é uma resposta válida para excluir o conteúdo de uma pasta (sem efeitos colaterais) .shutil.rmtree()
e a reconstrói comos.mkdir()
. E você obterá um diretório vazio com os bits padrão e herdados do proprietário e do modo. Embora você possa ter o privilégio de excluir o conteúdo e até o diretório, talvez não seja possível atrasar o proprietário original e os bits de modo no diretório (por exemplo, você não é um superusuário).Aqui está uma solução longa e feia, mas confiável e eficiente.
Resolve alguns problemas que não são abordados pelos outros respondentes:
shutil.rmtree()
de um link simbólico (que passará noos.path.isdir()
teste se ele vincular a um diretório; até o resultado tambémos.walk()
conterá diretórios simbólicos).Aqui está o código (a única função útil é
clear_dir()
):fonte
os.remove
, ao contrário darm
utilidade, tem o prazer de excluir somente leitura arquivos enquanto você possuí-los. Enquanto isso, se é um arquivo do qual você não possui apenas acesso somente leitura, não pode excluí-lo ou alterar suas permissões. Não conheço nenhuma situação em nenhum sistema em que você nãoos.remove
consiga excluir um arquivo somente leitura e ainda possa alterar suas permissões. Além disso, você usalchmod
, o que não existe no meu Mac, nem no Windows, de acordo com seus documentos. Para que plataforma esse código se destina ?!Estou surpreso que ninguém tenha mencionado o incrível
pathlib
para fazer este trabalho.Se você deseja apenas remover arquivos em um diretório, pode ser um oneliner
Para também remover diretórios recursivamente, você pode escrever algo como isto:
fonte
.iterdir()
em vez de.glob(...)
também deve funcionar.Um comentário anterior também menciona o uso de os.scandir no Python 3.5+. Por exemplo:
fonte
os.path.isdir()
não é uma maneira válida de distinguir entre um diretório regular e um link simbólico. Chamarshutil.rmtree()
um link simbólico gerará umaOSError
exceção.Você pode estar melhor usando
os.walk()
isso.os.listdir()
não distingue arquivos de diretórios e você terá problemas para tentar desvinculá-los rapidamente. Há um bom exemplo deos.walk()
como remover um diretório recursivamente aqui e dicas de como adaptá-lo às suas circunstâncias.fonte
Eu costumava resolver o problema desta maneira:
fonte
Ainda outra solução:
fonte
sh
não faz parte da biblioteca padrão e precisa ser instalado a partir do PyPI para que você possa usá-lo. Além disso, como isso realmente é chamadorm
em um subprocesso, não funcionará no Windows onderm
não existe. Isso também gerará uma exceção se a pasta contiver subdiretórios.Eu sei que é um tópico antigo, mas encontrei algo interessante no site oficial do python. Apenas para compartilhar outra ideia para remover todo o conteúdo de um diretório. Porque tenho alguns problemas de autorização ao usar shutil.rmtree () e não quero remover o diretório e recriá-lo. O endereço original é http://docs.python.org/2/library/os.html#os.walk . Espero que possa ajudar alguém.
fonte
Para excluir todos os arquivos dentro do diretório, bem como seus subdiretórios, sem remover as próprias pastas, basta fazer o seguinte:
fonte
Se você estiver usando um sistema * nix, por que não alavancar o comando system?
fonte
Maneira bastante intuitiva de fazer isso:
fonte
Bem, acho que esse código está funcionando. Ele não excluirá a pasta e você pode usar esse código para excluir arquivos com a extensão específica.
fonte
Eu tive que remover arquivos de 3 pastas separadas dentro de um diretório pai único:
Este código simples fez o truque para mim: (eu estou no Unix)
Espero que isto ajude.
fonte
Resolvi o problema
rmtree
makedirs
adicionandotime.sleep()
entre:fonte
Resposta para uma situação específica e limitada: supondo que você queira excluir os arquivos enquanto mantém a árvore de subpastas, você pode usar um algoritmo recursivo:
Talvez um pouco fora de tópico, mas acho que muitos achariam útil
fonte
os.walk
da maneira mostrada em stackoverflow.com/a/54889532/1709587 talvez seja uma maneira melhor de excluir todos os arquivos enquanto mantém intacta a estrutura de diretórios.Supondo
temp_dir
que seja excluído, um comando de linha única usandoos
seria:Nota: Este é apenas um alinhador para excluir arquivos 'Não exclui diretórios.
Espero que isto ajude. Obrigado.
fonte
Use o método abaixo para remover o conteúdo de um diretório, não o próprio diretório:
fonte
a maneira mais fácil de excluir todos os arquivos em uma pasta / remover todos os arquivos
fonte
Isso deve resolver o problema, basta usar o módulo OS para listar e remover!
Trabalhou para mim, qualquer problema me avise!
fonte