¿Cómo puedo eliminar todos los directorios vacíos en un subárbol? Usé algo como
find . -type d -exec rmdir {} 2>/dev/null \;
pero necesito que me ejecuten varias veces para eliminar directorios que solo contienen directorios vacíos. Además, es bastante lento, especialmente bajo cygwin.
Respuestas:
Combinando
find
opciones y predicados de GNU , este comando debería hacer el trabajo:-type d
se restringe a los directorios-empty
se restringe a los vacíos-delete
elimina cada directorioEl árbol se camina desde las hojas sin la necesidad de especificar,
-depth
ya que está implícito-delete
.fuente
-delete
ya implica,-depth
por lo que no necesita especificarlo manualmente.-mindepth 1
aquí, para evitar eliminar el directorio de inicio en sí, si estuviera vacío.!
tiene un significado especial para la concha. Necesitas escapar de eso. Algo así como:\! -name 'Completed'
justo antes-delete
debería funcionar. O simplemente coloca un archivo marcador en este directorio.Enumere los directorios profundamente anidados primero.
(Tenga en cuenta que la redirección se aplica al
find
comando como un todo, no solo armdir
. Redirigir solo pararmdir
causaría una desaceleración significativa ya que necesitaría invocar un shell intermedio).Puede evitar ejecutarse
rmdir
en directorios no vacíos pasando el-empty
predicado para buscar. GNU find prueba el directorio cuando está a punto de ejecutar el comando, por lo que se recogerán los directorios que se acaban de vaciar.Otra forma de acelerar sería agrupar las
rmdir
invocaciones. Es probable que ambos sean notablemente más rápidos que el original, especialmente bajo Cygwin. No espero mucha diferencia entre estos dos.El método más rápido depende de cuántos directorios no vacíos tenga. No puede combinarse
-empty
con métodos para agrupar invocaciones, porque los directorios que solo contienen directorios vacíos no están vacíos cuando losfind
mira.Otro método sería ejecutar múltiples pases. Si esto es más rápido depende de muchas cosas, incluso si toda la jerarquía de directorios puede permanecer en el caché del disco entre
find
ejecuciones.Alternativamente, use zsh. El calificador glob
F
coincide con directorios no vacíos, por lo que/^F
coincide con directorios vacíos. Los directorios que solo contienen directorios vacíos no pueden coincidir tan fácilmente.(Esto termina cuando
rmdir
recibe una línea de comando vacía).fuente
-p
? No hubiera pensado que haría la diferencia.-empty
debería funcionar con esta (aunque no estoy seguro exactamente cuánto ganará). Y muy, muy trivialmente, ya que probablemente no quieras eliminarlo.
, úsalo-mindepth 1
.-depth
argumento, que hacermdir -p
inútil. Ya he cambiado mi comentario. Los años 90 fueron mi intento original; No hay nada sorprendente aquí.rmdir
llamada de comando por completo, al menos con GNU find, con este comando:find . -depth -type d -empty -delete
Si solo agregas un
-p
a turmdir
, eso funcionará en una sola pasada. No será bonito u óptimo, pero debería tenerlo todo. Eso le dice a rmdir que elimine los directorios principales no vacíos del que está eliminando.Puede ahorrar un poco agregando la
-empty
prueba para buscar, para que no se moleste con directorios no vacíos.fuente
find . -depth -type d -exec rmdir {} +
es la respuesta más simple y estándar a esta pregunta.
Desafortunadamente, las otras respuestas dadas aquí dependen de mejoras específicas del proveedor que no existen en todos los sistemas.
fuente
find . -type d -printf "%d %p\n" |\ sort -nr |\ perl -pe 's/^\d+\s//;' |\ while read dir; do \ (rmdir "$dir" > /dev/null 2>&1); \ done
Así es como funciona:
rmdir
en la lista uno por unofuente
Utilizo estos alias para los
find
comandos de uso frecuente , especialmente cuando limpio el espacio en disco usando dupeguru , donde eliminar duplicados puede generar muchos directorios vacíos.Comentarios en el interior
.bashrc
para no olvidarlos más tarde cuando necesite modificarlo.fuente
rm -r */
El comando funcionó fácilmente para mí.rm
debería requerir la-f
eliminación forzosa de directorios con archivos.rm -r
solo debe eliminar directorios vacíos. Estoy abierto a por qué esto podría estar mal. Esto también debería dejar archivos, ya que*/
solo mira las carpetas.fuente
rm
está destinado principalmente a eliminar archivos. Si bien*/
solo coincide con directorios, no tengo idea de lo que hace en niveles más profundos. También puedo imaginar que solo funciona en algunos sistemas.