¿Cuál es la forma más rápida de mover un millón de imágenes de un directorio a otro en Linux?

14

Tengo un millón de imágenes que ocupan 30 GB de espacio en disco que deben moverse de un directorio local a otro directorio local.

¿Cuál sería la forma más eficiente de hacer esto? Utilizando mv? Utilizando cp? Utilizando rsync? ¿Algo más?

Necesito tomar estos:

/path/to/old-img-dir/*
                     00000000.jpg
                     --------.jpg  ## nearly 1M of them! ##
                     ZZZZZZZZ.jpg

y moverlos aquí:

/path/to/new/img/dir/
Ryan
fuente
55
No creo que pueda vencer mv, en términos de rendimiento, si los directorios de origen y destino residen en el mismo sistema de archivos.
Frédéric Hamidi

Respuestas:

26

rsync sería una mala elección porque realiza una gran cantidad de trabajo en segundo plano cliente / servidor que representa los sistemas locales y remotos.

mvEs probablemente la mejor opción. Si es posible, deberías intentarlo en mv directory_old directory_newlugar de hacerlo mv directory_old/* directory_new/. De esta manera, mueves una cosa en lugar de un millón de cosas.

Ricardo
fuente
66
+1 para el consejo de mover los directorios en lugar de los archivos.
Ex Umbris
44
Además, la expansión de comodines probablemente rompería los argumentos máximos admitidos mvsi estamos hablando de millones.
slhck
66
rsync maneja bien las transferencias en medios de almacenamiento local. Obliga a cosas como --whole-file (eliminando la implementación del algoritmo delta xfer) y evita otras cosas como --compresión que no sirven para nada en las transferencias locales. Si los directorios residen en diferentes sistemas de archivos, 'mv' no proporcionará ningún tipo de rendimiento. Si SÍ residen en el mismo sistema de archivos, simplemente 'mv' los directorios como dijeron estas personas.
UtahJarhead
Si hay muchas imágenes, el uso de un comodín de shell simple desbordará la línea de comando máxima.
Raúl Salinas-Monteagudo
1
Moverse entre discos seguirá moviendo todos los datos. En el mismo disco, mvsolo actualiza la información del inodo para que mv directory_old directory_newfuncione más rápido quemv directory_old/* directory_new
Anshul
14
find src_image_dir/ -type f -name '*.jpg' -print0 | xargs -0r mv -t dst_image_dir/ 
  • Esto no desbordará la expansión del argumento.
  • Puede especificar la extensión del archivo, si lo desea. (-nombre ...)
  • find -print0con le xargs -0permite usar espacios en los nombres.
  • xargs -rno se ejecutará a mvmenos que haya algo que mover. ( mvse quejará si no se proporcionan archivos de origen).
  • La sintaxis le mv -tpermite especificar primero el destino y luego los archivos de origen que necesita xargs.
  • Mover todo el directorio es, por supuesto, mucho más rápido, ya que se realiza en tiempo constante, independientemente de la cantidad de archivos que contiene, pero:
    • el directorio fuente desaparecerá por una fracción de tiempo y puede crearle problemas;
    • si el proceso está utilizando el directorio actual como directorio de salida (en contraste con referirse siempre a una ruta completa desde una ubicación que no se mueve), deberá reiniciarlo. (como lo hace con la rotación de registros ).

Por cierto, me preguntaría si realmente tengo que mover una gran cantidad de archivos a la vez. El procesamiento por lotes está sobrevalorado. Intento no acumular grandes cantidades de trabajo si puedo procesar las cosas en el momento en que se generan.

Raúl Salinas-Monteagudo
fuente
Esto funciona lo suficientemente bien como para mover archivos a través de sistemas de archivos en el mismo servidor. Lo suficientemente bien como para no molestarme en buscar una solución en rsync. Claro que tomó una o dos horas, pero funciona. Una cosa a tener en cuenta, si le da encontrar un nombre de directorio en lugar de "." - asegúrese de utilizar la barra diagonal final en el comando find, de lo contrario, el directorio se volverá a crear en el destino del comando mv.
Speeddymon
7

Si los dos directorios residen en el mismo sistema de archivos, utilícelos mven el DIRECTORIO y no en el contenido del directorio.

Si residen en dos sistemas de archivos diferentes, use rsync:

rsync -av /source/directory/ /destination

Observe el seguimiento /en la fuente. Esto significa que copiará el CONTENIDO del directorio y no el directorio en sí. Si deja la opción /desactivada, seguirá copiando los archivos, pero se ubicarán en un directorio llamado /destination/directory. Con el /, los archivos solo estarán en/destination

rsyncmantendrá la propiedad del archivo si lo ejecuta como root o si los archivos son de su propiedad. También mantendrá el mtimede cada archivo individual.

UtahJarhead
fuente
2
Para copiar una carpeta grande de un disco duro a un disco duro diferente, rsyncparece correr círculos mv. ¡Gracias por el consejo!
leo-the-manic
2
tar cf - dir1 | (cd dir2; tar xf -)

tar cf - dir1 | ssh remote_host "( cd /path/to/dir2; tar xf - )"

Cuando usa 'cp', cada archivo abre, lee, cierra, abre, escribe y cierra. Tar utiliza diferentes procesos para leer y escribir, así como múltiples pasos para operar en múltiples archivos a la vez. Incluso en una sola caja de CPU, las aplicaciones multiproceso son más rápidas.

maholt
fuente
2
Si bien esto puede responder la pregunta, sería una mejor respuesta si pudiera proporcionar alguna explicación de por qué lo hace.
DavidPostill
1
Si están en la máquina local, es probable que residan en el mismo sistema de archivos. Al usarlo tar c | tar xobtienes un costo de O (tamaño_total) en lugar de O (cuenta_archivos).
Raúl Salinas-Monteagudo
1

Como ambos, directorio_vejez y directorio_nuevo están en el mismo sistema de archivos que podría usar en cp -llugar de mvcomo una opción. cp -lcreará enlaces duros a los archivos originales. Cuando haya terminado con 'mover' y esté satisfecho con el resultado, puede eliminar estos archivos de directory_old. en términos de velocidad, será el mismo que 'mv', ya que primero crea los enlaces y luego elimina los originales. Pero este enfoque le permite comenzar desde el principio si esto tiene sentido

Sarga
fuente
0

Depende (tm). Si su sistema de archivos es copia-en-escritura, entonces copiar ( cpo rsync, por ejemplo) debería ser comparable a un movimiento. Pero para los casos más comunes, move ( mv) será el más rápido, ya que simplemente puede cambiar los datos que describen dónde se ubica un archivo (nota: esto está demasiado simplificado).

Entonces, en su instalación promedio de Linux, iría por mv.

EDITAR: @ Frédéric Hamidi tiene un buen punto en los comentarios: esto solo es válido si ambos están en el mismo sistema de archivos y disco. De lo contrario, los datos se copiarán de todos modos.

carlpett
fuente
0

Para copiar al menos ~ 10k de archivos (sin directorios), cp se quejó con:

no se puede ejecutar / bin / cp: lista de argumentos demasiado larga

La mejor opción es Rsync:

destino fuente rsync

¡Y se hizo muy rápido!

Nico
fuente
0

Si tiene espacio libre, archívelos en un único archivo .tar (sin compresión es más rápido) y luego mueva ese archivo y desarchívelo.

endolito
fuente
0

La naturaleza del destino determinaría la forma más eficiente de realizar esta tarea. Supongamos que está en un sistema local, su PWDes /ahora. y /acontiene los millones de imágenes. Nuestra tarea es mover todas las imágenes a /b, manteniendo toda la estructura del subdirectorio. Supongamos también /ay /bson puntos de montaje para dos particiones diferentes, cada una en un disco conectado localmente. Queremos hacer esta tarea con una lona. Esto puede llevar algún tiempo, así que asegúrese de que está utilizando screen, tmuxo bien ejecutar esto como un proceso de fondo.

tar -C /a -cf . | tar -C /b -xf -

Eso sería copiar todos los archivos y directorios en los /aque /b, por lo que ahora tendrá que limpiar /auna vez que confirme que ha completado sin error.

JM Becker
fuente