¿Cómo elimino recursivamente directorios con comodines?

52

Estoy trabajando a través de SSH en una WD My Book World Edition. Básicamente, me gustaría comenzar en un nivel de directorio particular y eliminar recursivamente todas las coincidencias de subdirectorios .Apple*. ¿Cómo iba a hacer eso?

Lo intenté

rm -rf .Apple* y rm -fR .Apple*

ninguno de los directorios eliminados que coinciden con ese nombre dentro de los subdirectorios.

codedog
fuente

Respuestas:

73

find es muy útil para realizar acciones selectivas en un árbol completo.

find . -type f -name ".Apple*" -delete

Aquí, -type fse asegura de que sea un archivo, no un directorio, y puede que no sea exactamente lo que desea, ya que también omitirá enlaces simbólicos, sockets y otras cosas. Puede usar ! -type d, lo que literalmente significa no directorios, pero también puede eliminar caracteres y bloquear dispositivos. Sugeriría mirar el -typepredicado en la página del manual para find.

Para hacerlo estrictamente con un comodín, necesita soporte avanzado de shell. Bash v4 tiene la globstaropción , que le permite unir recursivamente subdirectorios utilizando **. zshy kshtambién es compatible con este patrón. Usando eso, puedes hacerlo rm -rf **/.Apple*. Este no es el estándar POSIX y no es muy portátil, por lo que evitaría usarlo en un script, pero para una acción de shell interactiva única, está bien.

Shawn J. Goff
fuente
3
Puedo ponerme find . -type d -name .Apple*a trabajar: enumera todas las carpetas. Sin embargo, falla cuando agrego -deleteal final. Simplemente vuelve con el resumen de uso. Se ejecuta en BusyBox v1.1.1. Eso hace una diferencia?
codedog
1
-deletetampoco es POSIX. **fue introducido por zsha principios de los 90. Ahora está (por orden cronológico de aparición) también en ksh93, fish, bash y tcsh.
Stéphane Chazelas
1
+1 pararm -rf **/.Apple*
Andriy Boyko el
1
@codedog, si -deleteno funciona, use -exec rm -f {} +en su lugar.
Comodín el
1
¿Puedes llegar finda ser detallado cuando se elimina? Supongo que el método "globstar" haría esto agregando el -vinterruptor.
Demis
17

Me encontré con problemas usando findcon -deletedebido al comportamiento intencional de find(es decir, negarse a eliminar si la ruta se inicia con ./, lo que hacen en mi caso) como se indica en su página de manual:

 -delete

Eliminar los archivos y / o directorios encontrados. Siempre vuelve verdadero. Esto se ejecuta desde el directorio de trabajo actual a medida que find se repite en el árbol. No intentará eliminar un nombre de archivo con un carácter "/" en su ruta relativa a "." por razones de seguridad.
El procesamiento transversal primero en profundidad está implícito en esta opción.
Seguir enlaces simbólicos es incompatible con esta opción.

En cambio, solo pude hacer

find . -type d -name 'received_*_output' -exec rm -r {} +

Para su caso, parece que citar el globo (asterisco, *) fue la solución, pero quería proporcionar mi respuesta en caso de que alguien más tuviera el mismo problema.

NOTA: Anteriormente, mi respuesta era hacer lo siguiente, pero @Wildcard señaló las fallas de seguridad al hacerlo en los comentarios.

find . -type d -name 'received_*_output' | xargs rm -r
Palmadita
fuente
1
No hay una buena razón para usar xargsaquí. -exec rm -r {} \;o, mejor, -exec rm -r {} +lo hará también sin fallar en los nombres de archivos de caracteres especiales. Ver ¿Por qué es una mala práctica la salida de find?
Comodín el
Es bueno saberlo. No vale la pena un voto negativo, OMI, ya que el comando todavía hace el trabajo, pero se aprecia la optimización del rendimiento.
Pat
1
Si fuera solo una optimización de rendimiento, estaría de acuerdo con usted, pero no lo es. Es un agujero de seguridad. No está manejando correctamente los archivos con espacios en blanco en sus nombres, y un nombre de archivo creado con fines maliciosos provocará la pérdida de datos. Consulte también las implicaciones de seguridad de olvidarse de citar una variable en shells bash / POSIX ; parte de eso es aplicable y al menos puede darle una idea del tipo de problemas de los que estoy hablando.
Comodín
Intente mkdir -p $'blah\nDocuments\n/etc\n/home\n/received__output'en su directorio y luego ejecute el mismo comando nuevamente, si no cree que exista la posibilidad de pérdida de datos. O bien, dado que la cuestión es sobre Mac OS, mkdir -p $'blah\nDocuments\n/Users\n/Applications\n/received__output'. ( Advertencia: eliminarás todos tus archivos si haces esto. Ese es mi punto.)
Comodín
0

Lo que es posible es que no haya nada de malo en su comando rm / find, pero que el usuario con el que ha iniciado sesión no tiene permisos de eliminación. Úselo ls -lpara enumerar cosas con sus permisos, y puede identificar quién es usted con los comandos idy groups(cualquiera de los dos debería estar disponible). Si usted es el "usuario incorrecto" para hacer esto, deberá cambiar los permisos / propiedad de los archivos o cambiar a otro usuario.

Froztbyte
fuente
0

Tratar:

shopt -s dotglob           # using Bash
printf '%s\n' ./.Apple*    # test
#rm -rf ./.Apple*    
ene
fuente
1
dotglobEs inútil aquí. Vea esta página para ver un ejemplo de lo que hace dotglob.
anfetamáquina
-1

Comando simple:

rm `find ./ -name '.Apple*'` -rf

¡Buena suerte!

KimKha
fuente
44
Esto es extremadamente propenso a errores, encuentra la clave -exec.
Anton Barkovsky