eliminación masiva de archivos

eliminación masiva de archivos

Me gustaría eliminar todos los archivos txt, xls, pdf de un directorio, así como sus subdirectorios. Me gustaría guardar todo lo demás.

find . -type f ! -iname '*.xml$,.png$,.jpeg$,.gif$,' -delete

Eso parecía haberlo hecho, pero elimina algunos otros archivos que necesito. ¿Cómo puedo lograr eso sin eliminar nada más?

Respuesta1

Haz esto en su lugar:

find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -delete

También puedes usar expresiones regulares:

find . -type f -iregex '.*\.\(xml\|png\|jpeg\|gif\)$' -delete

Respuesta2

Básicamente, existen 4 formas de abordar este problema utilizando find.

Método n.° 1: usar-delete

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -delete

Como otros han mencionado en estas preguntas y respuestas, este método es el más rápido y el que requiere menos recursos. Citando delbuscar documentos en línea:

10.1.6 Usando la acción `-delete'


El método más eficiente y seguro para resolver este problema es utilizar la acción "-delete":

 find /var/tmp/stuff -mtime +90 -delete

Esta alternativa es más eficiente que cualquiera de las -exec' oracciones -execdir', ya que evita por completo la sobrecarga de bifurcar un nuevo proceso y usar exec' to run/bin/rm'. Normalmente también es más eficiente que xargs' for the same reason. The file deletion is performed from the directory containing the entry to be deleted, so thela acción -delete. Tiene las mismas ventajas de seguridad que la acción "-execdir".

La acción "-delete" fue introducida por la familia de sistemas operativos BSD.

NOTA:Una cosa a tener en cuenta con este enfoque es que el uso de -deleteimplica también el cambio -depth. ¿Qué quiere decir esto? Aquí tienes un ejemplo de cómo -deletepuedes quemarte si no tienes cuidado.

Por ejemplo, digamos que tengo un directorio de trabajo de subversion donde quiero limpiar algunos archivos, pero dejo intactos sus subdirectorios .svn. Podría usar el siguiente comando para lograr esto:

$ find . -not "(" -name .svn -type d -prune ")" -type f -print
./a.txt

Pero debido a que -deleteincluye un -depthmodificador, los archivos que realmente se tratarían:

$ find . -not "(" -name .svn -type d -prune ")" -type f -print -depth
./.svn/all-wcprops
./.svn/entries
./.svn/format
./.svn/text-base/a.txt.svn-base
./a.txt

Por este motivo, a la hora de utilizarlo -deletehay que tener cuidado.

Método #2 --exec command {} +

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -exec rm {} \+

En comparación con el -deletemétodo, esta es probablemente la siguiente mejor opción, en términos de rendimiento y portabilidad en Unix. La -exec ... {} +notación funciona de la siguiente manera:

desde la página de manual de búsqueda

Esta variante de la acción -exec ejecuta el comando especificado en los archivos seleccionados, pero la línea de comando se crea agregando cada nombre de archivo seleccionado al final; el número total de invocaciones del comando será mucho menor que el número de archivos coincidentes. La línea de comando está construida de manera muy similar a como xargs construye sus líneas de comando. Sólo se permite una instancia de `{}' dentro del comando. El comando se ejecuta en el directorio de inicio.

Entonces, en efecto, este método funciona de manera similar a xargs, pero sin tener que pasar por el aro de pasar la salida de un hallazgo a través de una tubería a xargs.

Método #3 -xargs

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' -print0 | xargs -0 rm -f

Creará find ... -print0una lista de archivos que coincidan con los criterios especificados. Luego, esta lista se pasa a través de la tubería a xargs. El -print0interruptor coloca un carácter ASCII NUL como separador entre cada resultado de la búsqueda. El -0encendido xargshace que se asuma que los archivos que se pasan están separados por caracteres ASCII NUL.

En comparación con los métodos n.° 1 y n.° 2, este tendrá un rendimiento similar al n.° 2; sin embargo, el -print0conmutador no es compatible universalmente en todos los Unix.

Método #4 --exec command {} \;

$ find . -type f -iname '*.xml' -o -iname '*.png'\
       -o -iname '*.jpeg' -o -iname '*.gif' | exec rm -f {} \;

En comparación con los primeros 3 métodos, este es el de menor rendimiento. Literalmente llama al rmcomando para cada archivo individual que findencuentra el comando.

Consideraciones adicionales sobre la seguridad

Una cosa que puede no ser tan obvia al utilizar cualquiera de los métodos anteriores es que algunos de ellos son más seguros que otros. Probablemente te estés diciendo a ti mismo... ¿seguridad? .. ¿qué? He aquí un ejemplo.

Asume tu root y ejecuta el siguiente comando:

$ find /var/tmp/somedir -type f -exec rm {} \;

Sin que usted lo sepa, alguien ha creado maliciosamente un enlace al /etcdirectorio en /var/tmp/somedir. Cuando se ejecute el comando anterior, el /etcdirectorio también se eliminará. Este problema existe con cualquiera de los métodos para eliminar archivos, excepto con la -deleteopción (método n.° 1).

tl;dr;

La forma más rápida y segura de eliminar archivos con la ayuda de buscar es utilizar -delete. El uso xargs -0puede tener un rendimiento similar, pero no es tan seguro. La -deleteacción no es completamente portátil. La alternativa portátil más eficiente es -exec ... +, pero es insegura y no es compatible con versiones de GNU findutils anteriores a la 4.2.12.

Referencias

Respuesta3

Hay una ligera inexactitud enrespuesta slm.

NOTA y descargo de responsabilidad: esto tiene que ser un comentario pararespuesta slmpero ahora mismo no puedo hacer comentarios todavía.

El ejemplo "alguien ha creado un enlace maliciosamente" dado enConsideraciones adicionales sobre la seguridadno es totalmente exacto tanto sobre los enlaces físicos de Unix como sobre los enlaces blandos de Unix.

Para comprender la diferencia entre los dos, consulteEnlace físico y enlaces simbólicos en Unixo búscalo en Google.

Para enlaces blandos (el tipo más utilizado de todos modos) tanto GNU findcomoBDS find no essiga enlaces simbólicos a menos que se utilice una -Lbandera específica para forzar el seguimiento de enlaces simbólicos. [Ver man find]

Por lo tanto, es probable que este ejemplo no sea un problema, a menos quefuerza findpara seguir enlaces suaves usando la -Lbandera. De todos modos, esta es la elección peligrosa.

Para enlaces físicos, findsiga el enlace aotro archivopero tenga en cuenta que el enlace físico a unotro directorio"probablemente fallará" como se ve man lnen GNU ln:

   -d, -F, --directory
          allow the superuser to attempt to hard link directories (note: will probably
          fail due to system restrictions, even for the superuser)

Por lo tanto, en primer lugar, probablemente sea imposible crear el enlace físico a un directorio y findno tendrá nada que seguir.

Tenga en cuenta que algunas lnimplementaciones de BDS no tienen ninguna -dopción.

información relacionada