Como faço para remover todos os arquivos .pyc de um projeto?

677

Renomeei alguns arquivos em um projeto bastante grande e quero remover os arquivos .pyc que eles deixaram para trás. Eu tentei o script bash:

 rm -r *.pyc

Mas isso não ocorre através das pastas como eu pensava. O que estou fazendo errado?

Teifion
fonte
11
Não funciona porque no UNIX, os globs são expandidos pelo shell, não pelo programa que está sendo executado. Se você tiver a.pyc e b.pyc no diretório atual e os diretórios foo e bar, rmserão chamados com argumentos [-r, a.pyc, b.pyc].
ephemient
1
Se você está se preocupando com empurrar o seu código para outras pessoas, você pode simplesmente adicioná-lo à .gitignore **/*.pycentão você não terá que se preocupar com isso novamente
bubakazouba

Respostas:

1165
find . -name "*.pyc" -exec rm -f {} \;
Bill the Lizard
fonte
384
O Find possui uma ação "-delete" embutida, para que você possa fazer exatamente #find . -name \*.pyc -delete
Christoffer
51
Mais importante, se essa é uma máquina de desenvolvimento, você pode definir PYTHONDONTWRITEBYTECODE = True e nunca precisará fazer isso novamente. Veja: esta resposta .
Mlissner
5
Você não está citando {}. O que aconteceria se acidentalmente dividisse a palavra e excluísse um caminho intermediário que é chamado como um fragmento do caminho que você encontrou?
Robottinosino
20
-deletenão faz parte da especificação POSIX e não existe garantia em todas as implementações de find.
Chepner
7
Se você está com medo - o que pode ser bom - faça um primeiro passe com -exec echo {} ou - se você está com muito medo - use rm -i {}, que pergunta a cada vez ou rm - v {}, para ver o que você exclui.
jeanM
1021

find . -name '*.pyc' -delete

Certamente o mais simples.

Andy Baker
fonte
21
Se a sua versão do findsuporta -delete; não faz parte do padrão POSIX.
Chepner
4
Isso ignora os arquivos e __pycache__diretórios .pyo . Veja minha resposta.
Wilfred Hughes
Eu usei o código da resposta aceita e funcionou, mas estes comandos são mais curtos e simples
Dap
3
-name '*.py?'para incluir.pyo, .pyc,...
cdosborn
2
VERIFIQUE -Delete é a última coisa no comando. Eu acidentalmente coloquei -delete logo após a descoberta. Apagou tudo!
Thinkanotherone 01/09
85

Na versão atual do debian você tem um pycleanscript que está no python-minimalpacote.

O uso é simples:

pyclean .
jb.
fonte
34
Vale ressaltar que o pyclean parece excluir apenas os arquivos .pyc para os quais há um arquivo .py correspondente (pelo menos no meu sistema - ubuntu 12.10.) Isso significa que não é muito útil em situações em que um arquivo de origem foi excluído e você deseja para limpar os arquivos .pyc restantes.
precisa saber é o seguinte
@holms pyclean(e agora py3clean) se originam em um pacote Debian e, portanto, não estão no RHEL.
duozmo
83

Adicione ao seu ~/.bashrc:

pyclean () {
        find . -type f -name "*.py[co]" -delete
        find . -type d -name "__pycache__" -delete
}

Isso remove todos os arquivos e __pycache__diretórios .pyc e .pyo . Também é muito rápido.

O uso é simplesmente:

$ cd /path/to/directory
$ pyclean
Wilfred Hughes
fonte
find . -type d -name "__pycache__" -deletegeralmente emitirá um aviso sobre um caminho ausente porque, aparentemente, o conteúdo será adicionado à fila antes da exclusão da pasta. 2>/dev/nulldeveria consertar isso.
Mad Físico
53

Se você estiver usando o bash> = 4.0 (ou zsh)

rm **/*.pyc

Observe que */*.pycseleciona todos os .pycarquivos nos subdiretórios imediatos de primeiro nível enquanto **/*.pycverifica recursivamente toda a árvore de diretórios. Como exemplo, foo/bar/qux.pycserá excluído por, rm **/*.pycmas não por */*.pyc.

As opções do shell globstar devem estar ativadas. Para habilitar globstar:

shopt -s globstar

e para verificar seu status:

shopt globstar
d0k
fonte
1
Qual é a diferença entre running rm **/*.pycvs rm */*.pyc? (Este último parecia estar a trabalhar para mim localmente.)
Taylor Edmiston
1
@TaylorEdmiston rm */*.pycirá apagar todos os .pycarquivos em todos os subdiretórios de profundidade 1. rm **/*.pycirá apagar todos os .pycarquivos em todos os subdiretórios de profundidade 0+
Adam Stewart
@AdamStewart Obrigado por adicionar isso. Para outros que tropeçam nessa discussão, o problema que eu estava enfrentando era que o bash da Apple enviado com o OS X não inclui a globstar ( **age como *quando executado em vez disso e a execução shopt globstargera um erro).
Taylor Edmiston
30

Eu costumava usar um alias para isso:

$ which pycclean

pycclean is aliased to `find . -name "*.pyc" | xargs -I {} rm -v "{}"'
miku
fonte
12
No debian atual, é pyclean.
jb.
7
Isso não lida bem com espaços em branco nos nomes de arquivos. Você deve usar find -print0e em xargs -0vez disso.
R3m0t
2
Por que você deseja ter código python com espaços nos nomes de arquivos / pastas? Isso é sintaticamente legal?
Coredumperror
@CoreDumpError, sim, de fato no Windows Python é instalado em um diretório com espaços ("Arquivos de Programas").
Paul Draper
O interpretador python pode ser instalado lá por padrão, mas dificilmente é um bom lugar para colocar seu código . Além disso, você certamente não gostaria que a pasta Arquivos de Programa fizesse parte da sua estrutura de pacotes, e é por isso que fiquei desconfiado com a sintaxe.
Coredumperror #
24

Para usuários do Windows:

del /S *.pyc
haki
fonte
Colocar isso em um script em lote torna as coisas super fáceis. Obrigado.
precisa
E se você estiver no Powershell, isso pode ser usado com "cmd" -> Executar comando -> "exit".
Np8 25/07/19
18
find . -name '*.pyc' -print0 | xargs -0 rm

A localização procura recursivamente os arquivos * .pyc. O xargs pega essa lista de nomes e a envia para rm. -Print0 e -0 dizem aos dois comandos para separar os nomes de arquivos com caracteres nulos. Isso permite que ele funcione corretamente em nomes de arquivos que contêm espaços e até mesmo um nome de arquivo que contém uma nova linha.

A solução com -exec funciona, mas gera uma nova cópia da rm para cada arquivo. Em um sistema lento ou com muitos arquivos, isso levará muito tempo.

Você também pode adicionar mais alguns argumentos:

find . -iname '*.pyc' -print0 | xargs -0 --no-run-if-empty  rm

iname adiciona insensibilidade a maiúsculas e minúsculas, como * .PYC. O no-run-if-empty impede que você obtenha um erro da rm se você não tiver esses arquivos.

Ron Romero
fonte
16
$ find . -name '*.pyc' -delete

Isso é mais rápido que

$ find . -name "*.pyc" -exec rm -rf {} \;
Moxdata
fonte
11

Além disso, as pessoas geralmente deseja remover todas *.pyc, *.pyoarquivos e __pycache__diretórios de forma recursiva no diretório atual.

Comando:

find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
Mithril
fonte
Essa é uma boa resposta, mas uma solução simples para Python seria multiplataforma e, portanto, preferível. Embora, pessoalmente, eu não me importo sobre o Windows provavelmente metade das vidas da população Python no Windows - e find, grepe amigos não funcionam lá.
31419 Peterino
Eles fazem se você instalar as ferramentas. Eu recomendo que todos os usuários da CLI do Windows façam isso para facilitar a
compatibilidade
8

Apenas para lançar outra variante na mistura, você também pode usar aspas como esta:

rm `find . -name *.pyc`
Clint Miller
fonte
5
Isso tem a pequena desvantagem de falhar se houver muitas correspondências, pois haverá muitos argumentos a serem passados rm.
chepner
8

Extensão Django

Nota: Esta resposta é muito específica para o projeto Django que já usa a Extensão Django .

python manage.py clean_pyc

A implementação pode ser visualizada em seu código fonte .

Yeo
fonte
7

recursivo completo

ll **/**/*.pyc
rm **/**/*.pyc
romuloigor
fonte
Interessante, como isso se compara às respostas de Andy e Bill?
Austin Henley
3
Um conjunto de **é redundante e, como na d0kresposta, você deve habilitar o globstar no bash 4+ para que isso funcione conforme o esperado. ou seja, faça shopt -s globstarou tenha isso em uma de suas festas de origem. arquivos.
Reinstate Monica Por favor,
1
Também llé comumente alias a algo como ls -l, mas não é realmente um comando ou portátil. Portanto, para listar recursivamente todos os .pycarquivos ., você deve fazer algo como echo **/*.pyccom o globstar ativado
Reinstate Monica Por favor,
3

Primeira corrida:

find . -type f -name "*.py[c|o]" -exec rm -f {} +

Adicione então:

export PYTHONDONTWRITEBYTECODE=1

Para ~ / .profile

Michael Benin
fonte
3

se você não quiser mais o .pyc, poderá usar esta única linha em um terminal:

export PYTHONDONTWRITEBYTECODE=1

Se você mudar de ideia:

unset PYTHONDONTWRITEBYTECODE
Kevin Sabbe
fonte
2

rm -rse repete em diretórios, mas apenas os diretórios aos quais você fornece rm. Ele também excluirá esses diretórios. Uma solução é:

for i in $( find . -name *.pyc )
do
  rm $i
done

findencontrará todos os arquivos * .pyc recursivamente no diretório atual, e o forloop percorrerá a lista de arquivos encontrados, removendo cada um.

Chris Lutz
fonte
Este funciona embora eu tenho que colocá-lo em um arquivo .sh e executar esse (que é bom por mim, eu vou estar usando este comando mais de uma vez)
Teifion
Acredito que colocar tudo em uma linha separada por ';' deve permitir que você execute no shell. Mas quando eu digito que na festança, aguarda o "feito" no final para executar qualquer coisa ...
Chris Lutz
É um péssimo antipadrão (e também muito comum, eu gostaria que ele desaparecesse): ele quebra com nomes de arquivos contendo espaços ou caracteres glob. E ele perde o sentido de findseu -execpredicado: find . -name '*.pyc' -exec rm {} +(melhor, mais curto, mais seguro, robusto, mais eficiente).
gniourf_gniourf
2
find . -name "*.pyc"|xargs rm -rf
PiyusG
fonte
1

Você pode correr find . -name "*.pyc" -type f -delete .

Mas use-o com precaução. Executar primeirofind . -name "*.pyc" -type f para ver exatamente quais arquivos você removerá.

Além disso, verifique se -delete é o último argumento em seu comando. Se você o colocar antes do argumento -name * .pyc, ele excluirá tudo.

gpap
fonte
1

Se você deseja excluir todos os arquivos .pyc da pasta do projeto.

Primeiro você tem

cd <path/to/the/folder>

encontre todo o arquivo .pyc e exclua.

find . -name \*.pyc -delete
Girish Vas
fonte