¿Cómo elimino todos los archivos .pyc de un proyecto?

678

Cambié el nombre de algunos archivos en un proyecto bastante grande y quiero eliminar los archivos .pyc que han dejado atrás. Probé el script bash:

 rm -r *.pyc

Pero eso no se repite a través de las carpetas como pensé que lo haría. ¿Qué estoy haciendo mal?

Teifion
fuente
11
No funciona porque en UNIX, los globos se expanden por el shell, no por el programa que se ejecuta. Si tiene a.pyc y b.pyc en el directorio actual, y los directorios foo y bar, rmserán llamados con argumentos [-r, a.pyc, b.pyc].
ephemient
1
si se está preocupando de empujar su código a otras personas, puedes añadirlo a la .gitignore **/*.pycentonces usted no tendrá que preocuparse de nuevo
bubakazouba

Respuestas:

1168
find . -name "*.pyc" -exec rm -f {} \;
Bill el lagarto
fuente
385
Find tiene una acción integrada "-delete", por lo que podría hacer solofind . -name \*.pyc -delete
Christoffer
51
Lo más importante, si se trata de una máquina de desarrollo, puede configurar PYTHONDONTWRITEBYTECODE = True, y nunca más tendrá que volver a hacerlo. Ver: esta respuesta .
mlissner
55
No estás citando {}. ¿Qué sucedería si accidentalmente dividiera palabras y eliminara una ruta intermedia que se llama como un fragmento de la ruta que encontró?
Robottinosino
20
-deleteno forma parte de la especificación POSIX y no se garantiza que exista en todas las implementaciones de find.
chepner
77
Si tiene miedo, lo que podría ser bueno, haga un primer pase con -exec echo {}, o, si tiene mucho miedo, use rm -i {} que le pregunta cada vez o rm - v {} para que vea qué usted borra
jeanM
1021

find . -name '*.pyc' -delete

Seguramente el más simple.

Andy Baker
fuente
21
Si su versión de findsoportes -delete; No es parte del estándar POSIX.
chepner
44
Esto ignora los archivos y __pycache__directorios .pyo . Mira mi respuesta.
Wilfred Hughes
Usé el código de la respuesta aceptada y funcionó, pero estos comandos son más cortos y simples
Dap
3
-name '*.py?'para incluir.pyo, .pyc,...
cdosborn
2
ASEGURARSE -delete es lo último en el comando. Accidentalmente puse -delete justo después del hallazgo. ¡Lo borró todo!
thinkanotherone
85

En la versión actual de Debian tiene un pycleanscript que está en el python-minimalpaquete.

El uso es simple:

pyclean .
jb.
fuente
34
Vale la pena señalar que pyclean parece eliminar solo archivos .pyc para los que hay un archivo .py correspondiente (al menos en mi sistema: ubuntu 12.10.) Esto significa que no es muy útil en situaciones en las que se ha eliminado un archivo fuente y desea para limpiar los archivos sobrantes .pyc.
tigerFinch
@holms pyclean(y ahora py3clean) se originan en un paquete Debian, y por lo tanto no están en RHEL.
duozmo
83

Añadir a su ~/.bashrc:

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

Esto elimina todos los archivos y directorios .pyc y .pyo __pycache__. También es muy rápido.

El uso es simplemente:

$ cd /path/to/directory
$ pyclean
Wilfred Hughes
fuente
find . -type d -name "__pycache__" -deletea menudo dará una advertencia sobre una ruta faltante porque aparentemente el contenido se agregará a la cola antes de que se elimine la carpeta. 2>/dev/nulldebería arreglar eso.
Físico loco
53

Si está usando bash> = 4.0 (o zsh)

rm **/*.pyc

Tenga en cuenta que */*.pycselecciona todos los .pycarchivos en los subdirectorios inmediatos de primer nivel mientras **/*.pycescanea recursivamente todo el árbol de directorios. Como ejemplo, foo/bar/qux.pycserá eliminado por rm **/*.pycpero no por */*.pyc.

Las opciones de shell globstar deben estar habilitadas. Para habilitar globstar:

shopt -s globstar

y para verificar su estado:

shopt globstar
d0k
fuente
1
¿Cuál es la diferencia en correr rm **/*.pycvs rm */*.pyc? (Esto último parecía funcionar para mí localmente.)
Taylor Edmiston
1
@TaylorEdmiston rm */*.pyceliminará todos los .pycarchivos en todos los subdirectorios de profundidad 1. rm **/*.pyceliminará todos los .pycarchivos en todos los subdirectorios de profundidad 0+
Adam Stewart
@AdamStewart Gracias por agregar esto. Para otros que tropezaron con este hilo, el problema que estaba experimentando era que el bash de Apple enviado con OS X no incluye globstar (por lo que **actúa como *cuando se ejecuta y ejecuta shopt globstararroja un error).
Taylor Edmiston
30

Solía ​​usar un alias para eso:

$ which pycclean

pycclean is aliased to `find . -name "*.pyc" | xargs -I {} rm -v "{}"'
miku
fuente
12
En debian actual es pyclean.
jb.
77
Esto no se ocupa bien del espacio en blanco en los nombres de archivo. Deberías usar find -print0y en su xargs -0lugar.
r3m0t
2
¿Por qué querrías tener código python con espacios en los nombres de archivo / carpeta? ¿Es eso sintácticamente legal?
coredumperror
@CoreDumpError, sí, de hecho en Windows Python se instala en un directorio con espacios ("Archivos de programa").
Paul Draper
El intérprete de Python puede instalarse allí de forma predeterminada, pero no es un buen lugar para colocar su código . Además, ciertamente no querrá que la carpeta Archivos de programa forme parte de la estructura de su paquete, por lo que desconfiaba de la sintaxis.
coredumperror
24

Para usuarios de Windows:

del /S *.pyc
haki
fuente
Poner esto en un script por lotes hace que las cosas sean muy fáciles. Gracias.
Nick Gotch
Y si está en Powershell, esto se puede usar con "cmd" -> Ejecutar comando -> "salir".
np8
18
find . -name '*.pyc' -print0 | xargs -0 rm

La búsqueda busca de forma recursiva archivos * .pyc. El xargs toma esa lista de nombres y la envía a rm. El -print0 y el -0 le dicen a los dos comandos que separen los nombres de los archivos con caracteres nulos. Esto le permite funcionar correctamente en nombres de archivos que contienen espacios, e incluso en un nombre de archivo que contiene una nueva línea.

La solución con -exec funciona, pero genera una nueva copia de rm para cada archivo. En un sistema lento o con una gran cantidad de archivos, eso llevará demasiado tiempo.

También podría agregar un par más de argumentos:

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

iname agrega insensibilidad a mayúsculas y minúsculas, como * .PYC. El no-run-if-empty le impide obtener un error de rm si no tiene dichos archivos.

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

Esto es más rápido que

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

Además, la gente por lo general quieren eliminar todos *.pyc, *.pyoarchivos y __pycache__directorios de forma recursiva en el directorio actual.

Mando:

find . | grep -E "(__pycache__|\.pyc|\.pyo$)" | xargs rm -rf
Mitril
fuente
Esta es una buena respuesta, pero una solución simple de Python sería multiplataforma y, por lo tanto, preferible. Mientras que, en lo personal, no me importa acerca de Windows probablemente la mitad de la población vive Python en Windows - y find, grepy amigos no trabajo allí.
Peterino
Lo hacen si instala las herramientas. Me gustaría recomendar cada usuario de Windows CLI lo hacen para aliviar la cruz-compat: superuser.com/questions/168202/...
DylanYoung
8

Solo para agregar otra variante a la mezcla, también puede usar comillas inversas como esta:

rm `find . -name *.pyc`
Clint Miller
fuente
55
Esto tiene el pequeño inconveniente de fallar si hay demasiadas coincidencias, ya que habrá demasiados argumentos para pasar rm.
chepner
7

recursivo completo

ll **/**/*.pyc
rm **/**/*.pyc
romuloigor
fuente
Interesante, ¿cómo se compara esto con las respuestas de Andy y Bill?
Austin Henley
3
Un conjunto de **es redundante, y como en d0kla respuesta, debe tener globstar habilitado en bash 4+ para que esto funcione según lo previsto. es decir, hacer shopt -s globstaro tener eso en uno de sus bash de origen. archivos.
Vuelva a instalar Monica Please
1
También llsuele tener un alias para algo así ls -l, pero no es realmente un comando o portátil. Por lo tanto, para enumerar recursivamente todos los .pycarchivos ., en su lugar, debe hacer algo como echo **/*.pyccon globstar habilitado
Monica Please
3

Primer intento:

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

Luego añade:

export PYTHONDONTWRITEBYTECODE=1

A ~ / .profile

Michael Benin
fuente
3

si ya no quieres .pyc puedes usar esta única línea en una terminal:

export PYTHONDONTWRITEBYTECODE=1

si cambias tu mente:

unset PYTHONDONTWRITEBYTECODE
Kevin Sabbe
fuente
2

rm -rvuelve a aparecer en directorios, pero solo en los directorios que le das rm. También eliminará esos directorios. Una solución es:

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

findencontrará todos los archivos * .pyc de forma recursiva en el directorio actual, y el forciclo iterará a través de la lista de archivos encontrados, eliminando cada uno.

Chris Lutz
fuente
Este funciona aunque tengo que ponerlo en un archivo .sh y ejecutarlo (lo cual está bien para mí,
usaré
Creo que ponerlo todo en una línea separada con ';' s debería permitirle ejecutarlo en el shell. Pero cuando escribo que en bash, esperas fiesta para los "hecho" al final para ejecutar cualquier cosa ...
Chris Lutz
Es un antipatrón horrible (y también muy común, desearía que pudiera desaparecer): se rompe con nombres de archivos que contienen espacios o caracteres globales. Y pierde el sentido de findsu -execpredicado: find . -name '*.pyc' -exec rm {} +(más agradable, más corto, más seguro, robusto, más eficiente).
gniourf_gniourf
2
find . -name "*.pyc"|xargs rm -rf
PiyusG
fuente
1

Tu puedes correr find . -name "*.pyc" -type f -delete .

Pero úsalo con precaución. Corre primerofind . -name "*.pyc" -type f para ver exactamente qué archivos eliminará.

Además, asegúrese de que -delete sea el último argumento en su comando. Si lo coloca antes del argumento -name * .pyc, eliminará todo.

gpap
fuente
1

Si desea eliminar todos los archivos .pyc de la carpeta del proyecto.

Primero tienes

cd <path/to/the/folder>

luego encuentre todo el archivo .pyc y elimínelo.

find . -name \*.pyc -delete
Vas girish
fuente