2012-07-05 14 views
6

Como sé que los comandos como¿Cuál es la mejor y la manera más rápida para eliminar gran directorio que contiene miles de archivos (en Ubuntu)

find <dir> -type f -exec rm {} \; 

no son la mejor variante para eliminar gran cantidad de archivos (archivos totales , incluida la subcarpeta). Funciona bien si tiene poca cantidad de archivos, pero si tiene más de 10 mln de archivos en subcarpetas, puede colgar un servidor.

¿Alguien sabe algún comando específico de Linux para resolver este problema?

+1

Lo que debe ser rápido, creando espacio o eliminando el directorio.Si el segundo, 'mv' it (muy rápido), luego elimínelo. –

Respuesta

5

He aquí un ejemplo script bash:

#!/bin/bash 

local LOCKFILE=/tmp/rmHugeNumberOfFiles.lock 

# this process gets ultra-low priority 
ionice -c2 -n7 -p $$ > /dev/null 
if [ $? ]; then 
    echo "Could not set disk IO priority. Exiting..." 
    exit 
fi 
renice +19 -p $$ > /dev/null 
if [ $? ]; then 
    echo "Could not renice process. Exiting..." 
    exit 
fi 

# check if there's an instance running already. If so--exit 
if [ -e ${LOCKFILE} ] && kill -0 `cat ${LOCKFILE}`; then 
    echo "An instance of this script is already running." 
    exit 
fi 

# make sure the lockfile is removed when we exit. Then: claim the lock 
trap "command rm -f -- $LOCKFILE; exit" INT TERM EXIT 
echo $$ > $LOCKFILE 

# also create a tempfile, and make sure that's removed too upon exit 
tmp=$(tempfile) || exit 
trap "command rm -f -- '$tmp'" INT TERM EXIT 



# ---------------------------------------- 
# option 1 
# ---------------------------------------- 
# find your specific files 
find "$1" -type f [INSERT SPECIFIC SEARCH PATTERN HERE] > "$tmp" 
cat $tmp | rm 

# ---------------------------------------- 
# option 2 
# ---------------------------------------- 
command rm -r "$1" 



# remove the lockfile, tempfile 
command rm -f -- "$tmp" $LOCKFILE 

Este script comienza estableciendo su propio proceso de prioridad y prioridad de diskIO a valores muy bajos, para garantizar que otros procesos en ejecución no se vean afectados lo más posible.

Luego se asegura de que sea ÚNICAMENTE el proceso en ejecución.

El núcleo de la secuencia de comandos depende de su preferencia. Puede usar rm -r si está seguro de que todo el directorio puede eliminarse indebidamente (opción 2) o puede usar find para eliminar archivos más específicos (opción 1, posiblemente utilizando las opciones de línea de comando "$ 2" y onw. Para mayor comodidad).

En la realización anterior, la opción 1 (find) primera salida a todo a un archivo temporal, por lo que la función rm sólo se le llama una vez en lugar de después de cada archivo encontrado por find. Cuando la cantidad de archivos es enorme, esto puede representar un ahorro de tiempo considerable. A la baja, el tamaño del archivo temporal puede convertirse en un problema, pero esto solo es probable si está borrando literalmente miles de millones de archivos, además, porque el disco tiene una prioridad tan baja, usando un archivo temporal seguido de un solo rm puede en total sea ​​más lento que usando la opción find (...) -exec rm {} \;. Como siempre, debe experimentar un poco para ver qué se adapta mejor a sus necesidades.

EDITAR: Según lo sugerido por el usuario946850, también puede omitir todo el archivo de temp y usar find (...) -print0 | xargs -0 rm. Esto tiene una huella de memoria más grande, ya que todas las rutas completas a todos los archivos coincidentes se insertarán en la RAM hasta que el comando find haya finalizado por completo. Por el lado positivo: no hay archivos adicionales IO debido a las escrituras en el archivo temporal. Cuál elegir depende de su caso de uso.

1

El conmutador (recursivo) -r también quita todo lo que está debajo de un directorio, incluidos los subdirectorios. (Su mandato no elimina los directorios, sólo los archivos.)

También puede acelerar el find enfoque:

find -type f -print0 | xargs -0 rm 
+0

xargs tomará los archivos un grupo a la vez, e incluso esperará a que los procesos terminen primero. Quizás sea más eficiente que 'find ... -exec rm {} \;' porque eso ejecuta un proceso para cada archivo. El problema con xargs es que no maneja el espacio en blanco, pero las banderas '-print0' y' -0' manejan ese problema. –

7

Puede parecer extraño, pero:

$ rm -rf <dir> 
+2

Sería en este punto que alguien debería decirte que tengas cuidado. La opción '-f' fuerza el borrado sin avisos; ejecutar esto en el lugar incorrecto puede causar estragos graves en su sistema ... pruébelo y acostúmbrese al comando antes de ejecutarlo en su servidor. – Lix

+0

Esto es mejor para Ubuntu 16.04 LTS en agosto de 2017. – SDsolar

0

Intenté cada uno de estos comandos, pero el problema era que el proceso de eliminación bloqueaba el disco y, como ningún otro proceso podía acceder, había un gran aluvión de procesos que intentaban acceder al disco. el problema es peor Ejecute "iotop" y vea cuánto disco está usando su proceso.

Aquí está el script de Python que resolvió mi problema.Borra 500 archivos a la vez, luego toma un descanso de 2 segundos para permitir que los otros procesos hagan su trabajo y luego continúa.

import os, os.path 
import time 

for root, dirs, files in os.walk('/dir/to/delete/files'): 
    i = 0 
    file_num = 0 
    for f in files: 
     fullpath = os.path.join(root, f) 
     i = i + 1 
     file_num = file_num + 1 
     os.remove(fullpath) 
     if i%500 == 1: 
      time.sleep(2) 
      print "Deleted %i files" % file_num 

Espero que esto ayude a algunas personas.

0

Si tiene que lidiar con la edición límite de espacio en un árbol muy grande (en mi caso muchas ramas forzosamente), que a veces ser colgado mientras se ejecuta el hallazgo y el proceso de eliminar -

Aquí hay un script que me horario diario para encontrar todos los directorios con archivo específico ("ChangesLog.txt"), y luego Ordenar todos los directorios encontrado que se mayores de 2 días, y retirar el primer directorio emparejado (cada horario podría haber un nuevo partido):

bash -c "echo @echo Creating Cleanup_Branch.cmd on %COMPUTERNAME% - %~dp0 > Cleanup_Branch.cmd" 
bash -c "echo -n 'bash -c \"find ' >> Cleanup_Branch.cmd" 
rm -f dirToDelete.txt 
rem cd. > dirToDelete.txt 
bash -c "find .. -maxdepth 9 -regex ".+ChangesLog.txt" -exec echo {} >> dirToDelete.txt \; & pid=$!; sleep 100; kill $pid " 
sed -e 's/\(.*\)\/.*/\1/' -e 's/^./"&/;s/.$/&" /' dirToDelete.txt | tr '\n' ' ' >> Cleanup_Branch.cmd 
bash -c "echo -n '-maxdepth 0 -type d -mtime +2 | xargs -r ls -trd | head -n1 | xargs -t rm -Rf' >> Cleanup_Branch.cmd" 
bash -c 'echo -n \" >> Cleanup_Branch.cmd' 
call Cleanup_Branch.cmd 

Nota: los requisitos

  1. Eliminación de sólo aquellos directorios con "ChangesLog.txt", ya que no se deben eliminar otros directorios viejos.
  2. Llamar a los comandos del sistema operativo en cygwin directamente, ya que de lo contrario se utilizaron los comandos predeterminados de Windows.
  3. Recopilando los directorios para eliminar en el archivo de texto externo, con el fin de guardar resultados de búsqueda, ya que a veces el proceso de búsqueda se ha colgado.
  4. Configurando un tiempo de espera al proceso de búsqueda usando & procesando el proceso de fondo después de 100 segundos.
  5. Ordenando primero los directorios más antiguos, para la prioridad de eliminación.
0

Si tiene una versión razonablemente moderna de find (4.2.3 o superior), puede utilizar la opción -delete.

find <dir> -type f -delete 

Si tiene la versión 4.2.12 o superior se puede tomar ventaja de xargs línea de comandos de estilo de apilamiento a través de la \+ modificador -exec. De esta forma, no ejecuta una copia separada de /bin/rm para cada archivo.

find <dir> -type f -exec rm {} \+ 
0

Los comandos anteriores son buenos.

rm -rf directory/ también funciona más rápido para mil millones de archivos en una carpeta. Intenté eso.

0

Puede crear un directorio vacío y RSYNC en el directorio que necesita vaciar. Usted evitará el tiempo de espera y la memoria hacia fuera la edición

+0

Si bien esto podría ser una pista valiosa para resolver el problema, una respuesta realmente necesita demostrar la solución. Por favor [edite] para proporcionar un código de ejemplo para mostrar lo que quiere decir (por ejemplo, no mencionó el indicador '--delete', pero eso será evidente en su respuesta). Alternativamente, considere escribir esto como un comentario en su lugar. –

+0

Por favor, edite con más información. Se desalientan las respuestas de solo código y "prueba esto", ya que no contienen contenido que se pueda buscar y no explican por qué alguien debe "probar esto". – abarisone

+0

Ídem. Me gustaría ver este trabajo. POR FAVOR, muestra cómo. – SDsolar

0

Si desea eliminar toneladas de archivos tan pronto como sea posible, intente esto:

find . -type f -print0 | xargs -P 0 -0 rm -f

cuenta que la opción -P hará xargs procesos de uso ya que muchos como sea posible.

Cuestiones relacionadas