Eliminar todos los subdirectorios excepto uno

10

Supongamos que bajo el directorio actual, hay múltiples subdirectorios, y uno se llama A.

¿Cómo eliminar todos los subdirectorios excepto A con Bash?

anon
fuente

Respuestas:

23

Bash ha extendido globbing (primera prueba, luego elimine el eco):

shopt -s extglob
echo rm -rf !(A)
TheBonsai
fuente
(antes de que olvide - es posible desactivar la terminación historia estilo CSH, en Bash3 hay un error mientras se ignora (set + H!.
+1 Bash si está lleno de sorpresas! A veces son agradables como este.
Aleksandr Levchuk el
Wauw muy agradable por cierto! Funciona como se esperaba. Con shopt | grep extPuede ver si el complemento está habilitado.
peligro89
14
find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;
dotjoe
fuente
10

Qué pasa:

mv A /tmp/
rm * -rf
mv /tmp/A .

Esto evita algo del "miedo" de un error tipográfico en los otros comandos.

Brent
fuente
1
+1 por hacer lo correcto en lugar de esperar que las herramientas sean lo suficientemente inteligentes. Aún así, una noche, cuando estaba aprendiendo Linux, copié el núcleo en / tmp antes de hacer mi primera compilación. no tuvo éxito, pero borré el viejo, así que dije 'no te preocupes, tengo una copia' solo para descubrir que una tarea cron de medianoche lo había borrado con cada archivo de más de una semana en / tmp. Tuve que volver a compilar y esta vez hacerlo bien, ¡o no reiniciar para mí!
Javier
mejor respuesta publicada :)
warren
3

Algo como

find . -type d -not -name A -exec rm -ir {} \;

debería hacer.

editar

Realmente debería ser

find . -type d -maxdepth 1 -not -name A -exec rm -ir {} \;

para evitar que se findrepita debajo de A.

rev agnul
fuente
3
Pero, esto también eliminaría cualquier subdirectorio debajo de A como A / foo y A / bar, pero preservaría A / A.
TCampbell
¡Frio! Preguntas y answert consigue migrar desde SO a SF ... pero mi texto de arriba se perdió ...
agnul
Debería ser mejor intercambiar maxdepth y escribir argumentos como este: find. -maxdepth 1 -type d -not -name A -exec rm -ir {} \;
Spawnrider
1

Normalmente hago esto elaborando un comando ls que lo hace bien primero. No estoy en una máquina Unix, pero algo así como:

ls -lda "[^ A]"

Una vez que lo hagas bien, canalízalo a un comando

ls -lda "[^ A]" | xargs rm -rf

Siéntase libre de editar arriba si tengo mi expresión regular incorrecta ...

Tim Hoolihan
fuente
No debe analizar ls: mywiki.wooledge.org/ParsingLs
hasta nuevo aviso.
1

Si quieres ser más flexible pero manual, puedes hacer:

ls > /tmp/foo
edit /tmp/foo as you like
xargs -a /tmp/foo rm -r

De esa manera puedes hacer munging general.

Joe Beda
fuente
1

Aquí hay una manera. Tenga cuidado con este tipo de cosas, sin embargo, es tan poderoso que solo puede usarse para bien o para mal ...

encontrar * -tipo d | grep -v "^ A" | xargs rm -rf
Don Branson
fuente
1

No use find como algunas personas han mostrado con -exec y rm sin pasar -print0 para encontrar y -0 a xargs. Se confundirá en los nombres de archivos con espacios o líneas nuevas:

$ mkdir 'foo foo'
$ mkdir foo$'\n'foo 
$ find . -type d -exec rm -ir {} \;
rm: cannot remove directory `.'
rm: remove directory `./foo\nfoo'? y
find: `./foo\nfoo': No such file or directory
rm: remove directory `./foo foo'? y
find: `./foo foo': No such file or directory

En su lugar, use find -print0 con xargs -0, '-exec command {} +', o -delete si su búsqueda lo admite.

Kyle Brandt
fuente
1

Además del ejemplo anterior de:

find -maxdepth 1 -type d -not -name A -not -name "." -exec rm -ir {} \;

también puedes hacer:

find some/subdir -mindepth 1 -maxdepth 1 -type d -not -name A -exec rm -ir {} \;

para evitar tener que hacerlo cd some/subdirprimero.

Lurchman
fuente