GNU/Linux >> Tutoriales Linux >  >> Linux

¿Eliminar todos los archivos excepto en un determinado subdirectorio con Buscar?

Quiero eliminar recursivamente todos los archivos a los que no se accedió en un tiempo en la carpeta a , excepto todos los archivos en la subcarpeta b .

find a ( -name b -prune ) -o -type f -delete

Sin embargo, recibo un mensaje de error:

find:la acción -delete activa automáticamente - depth, pero -prune no
hace nada cuando - depth está en efecto. Si desea continuar de todos modos,
simplemente use explícitamente la opción -profundidad.

Agregando -depth hace que todos los archivos en b a incluir, que no suceder.

¿Alguien conoce una forma segura de hacer que esto funcione?

Respuesta aceptada:

una forma es usar -exec rm en lugar de -delete .

find a ( -name b -prune ) -o -type f -exec rm {} +

alternativamente use -not -path en lugar de -prune :

find a -not -path "*/b*" -type f -delete

Explicación por qué -prune colisiona con -delete :

encuentra quejas cuando intentas usar -delete con -prune porque -delete implica -depth y -depth hace -prune ineficaz.

observe el comportamiento de find con y sin -depth :

$ find foo/
foo/
foo/f1
foo/bar
foo/bar/b2
foo/bar/b1
foo/f2

No hay garantía sobre el orden en un solo directorio. Pero hay una garantía de que un directorio se procesa antes que su contenido. Nota foo/ antes de cualquier foo/* y foo/bar antes de cualquier foo/bar/* .

Esto se puede revertir con -depth .

$ find foo/ -depth
foo/f2
foo/bar/b2
foo/bar/b1
foo/bar
foo/f1
foo/

Tenga en cuenta que ahora todos los foo/* aparecer antes de foo/ . Lo mismo con foo/bar .

más explicación:

  • -prune evita que find descienda a un directorio. En otras palabras -prune salta el contenido del directorio. En tu caso -name b -prune significa que cuando find llega a un directorio con el nombre b omitirá el directorio, incluidos todos los subdirectorios.
  • -depth hace que find procese el contenido de un directorio antes que el propio directorio. Eso significa que para cuando find llegue a procesar la entrada del directorio b su contenido ya ha sido procesado. Así -prune es ineficaz con -depth en vigor.
  • -delete implica -depth para que pueda eliminar primero el contenido y luego el directorio vacío. -delete se niega a eliminar directorios que no estén vacíos.

Explicación del método alternativo:

find a -not -path "*/b*" -type f -delete

Esto puede o no ser más fácil de recordar.

Este comando aún desciende al directorio b y procesa cada archivo en él solo para -not para rechazarlos. Esto puede ser un problema de rendimiento si el directorio b es enorme.

-path funciona de manera diferente a -name . -name solo coincide con el nombre (del archivo o directorio) mientras que -path coincide con la ruta completa. Por ejemplo observe la ruta /home/lesmana/foo/bar . -name bar coincidirá porque el nombre es bar . -path "*/foo*" coincidirá porque la cadena /foo está en el camino. -path tiene algunas complejidades que debe comprender antes de usarlo. Lea la página man de find para más detalles.

Relacionado:ado -Buscar significado- ¡Búsqueda en el diccionario!

Tenga en cuenta que esto no es 100% infalible. Hay posibilidades de "falsos positivos". La forma en que el comando está escrito arriba omitirá cualquier archivo que tenga un directorio principal cuyo nombre comience con b (positivo). Pero también omitirá cualquier archivo cuyo nombre comience con b independientemente de la posición en el árbol (falso positivo). Esto se puede solucionar escribiendo una mejor expresión que "*/b*" . Eso se deja como ejercicio para el lector.

Supongo que usaste a y b como marcadores de posición y los nombres reales se parecen más a allosaurus y brachiosaurus . Si pones brachiosaurus en lugar de b entonces la cantidad de falsos positivos se reducirá drásticamente.

Al menos los falsos positivos serán no eliminado, por lo que no será tan trágico. Además, puede verificar si hay falsos positivos ejecutando primero el comando sin -delete (pero recuerda colocar la -depth implícita ) y examine la salida.

find a -not -path "*/b*" -type f -depth

Linux
  1. ¿Cómo encontrar archivos con una determinada subruta?

  2. Encuentra todos los archivos con un nombre que contenga una cadena

  3. Elimine todos los archivos excepto los 3 más nuevos en bash script

  4. ¿Encontrar directorios con todos los archivos dentro de más de X?

  5. Eliminar todas las carpetas dentro de una carpeta excepto una con un nombre específico

3 formas de eliminar todos los archivos de un directorio excepto uno o algunos archivos con extensiones

Encuentra archivos perdidos con Scalpel

Eliminar archivos coincidentes en todos los subdirectorios

Cómo eliminar todos los archivos que comienzan con una determinada cadena en Linux

¿Cómo eliminar todos los archivos en un directorio excepto algunos?

Configure nginx.conf para denegar todas las conexiones excepto a ciertos archivos o directorios