Quel est le moyen le plus rapide pour déplacer un million d'images d'un répertoire à un autre sous Linux?

14

J'ai un million d'images qui occupent 30 Go d'espace disque qui doivent être déplacés d'un répertoire local vers un autre répertoire local.

Quelle serait la façon la plus efficace de procéder? En utilisant mv? En utilisant cp? En utilisant rsync? Autre chose?

Je dois les prendre:

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

et déplacez-les ici:

/path/to/new/img/dir/
Ryan
la source
5
Je ne pense pas que vous puissiez battre mv, en termes de performances, si les répertoires source et cible résident dans le même système de fichiers.
Frédéric Hamidi

Réponses:

26

rsync serait un mauvais choix car il fait beaucoup de travail en arrière-plan client / serveur qui tient compte des systèmes locaux et distants.

mvest probablement le meilleur choix. Si possible, vous devriez essayer mv directory_old directory_newplutôt que mv directory_old/* directory_new/. De cette façon, vous déplacez une chose au lieu d'un million de choses.

Richard
la source
6
+1 pour le conseil de déplacer les répertoires au lieu des fichiers.
Ex Umbris
4
De plus, l'extension générique briserait probablement le maximum d'arguments pris en charge mvsi nous parlons de millions.
slhck
6
rsync gère très bien les transferts sur les supports de stockage locaux. Cela force des choses comme --whole-file (en supprimant l'implémentation de l'algorithme delta xfer) et empêche d'autres choses comme --compression qui ne servent à rien dans les transferts locaux. Si les répertoires résident sur différents systèmes de fichiers, 'mv' ne fournira aucune sorte de performance. S'ils résident sur le même système de fichiers, alors «mv» les répertoires comme ces gens l'ont dit.
UtahJarhead
S'il y a beaucoup d'images, l'utilisation d'un simple caractère générique de shell débordera la ligne de commande maximale.
Raúl Salinas-Monteagudo
1
Le déplacement entre les disques déplacera toujours toutes les données. Sur le même disque, mvmet à jour les informations d'inode afin de mv directory_old directory_newfonctionner plus rapidement quemv directory_old/* directory_new
Anshul
14
find src_image_dir/ -type f -name '*.jpg' -print0 | xargs -0r mv -t dst_image_dir/ 
  • Cela ne débordera pas l'expansion des arguments.
  • Vous pouvez spécifier l'extension de fichier, si vous le souhaitez. (-Nom ...)
  • find -print0avec xargs -0vous permet d'utiliser des espaces dans les noms.
  • xargs -rne fonctionnera mvque s'il y a quelque chose à déplacer. ( mvse plaindra si aucun fichier source n'est fourni).
  • La syntaxe mv -tvous permet de spécifier d'abord la destination, puis les fichiers source nécessaires à xargs.
  • Le déplacement de tout le répertoire est bien sûr beaucoup plus rapide, car il se déroule en temps constant quel que soit le nombre de fichiers qu'il contient, mais:
    • le répertoire source disparaîtra pendant une fraction de temps et cela pourrait vous créer des problèmes;
    • si le processus utilise le répertoire courant comme répertoire de sortie (contrairement à toujours faire référence à un chemin complet depuis un emplacement non mobile), vous devrez le relancer. (comme vous le faites avec la rotation des journaux ).

Soit dit en passant, je me demanderais si je dois vraiment déplacer une si grande quantité de fichiers à la fois. Le traitement par lots est surévalué. J'essaie de ne pas accumuler d'énormes quantités de travail si je peux traiter les choses au moment où elles sont générées.

Raúl Salinas-Monteagudo
la source
Cela fonctionne assez bien pour déplacer des fichiers à travers des systèmes de fichiers sur le même serveur. Assez bien que je n'ai pas pris la peine de chercher une solution dans rsync. Bien sûr, cela a pris une heure ou deux, mais cela fonctionne. Une chose à noter, si vous donnez trouver un nom de répertoire au lieu de "." - assurez-vous d'utiliser la barre oblique de fin dans la commande find, sinon le répertoire sera recréé dans la destination de la commande mv.
Speeddymon
7

Si les deux répertoires résident sur le même système de fichiers, utilisez- mvle dans le RÉPERTOIRE et non le contenu du répertoire.

S'ils résident sur deux systèmes de fichiers différents, utilisez rsync:

rsync -av /source/directory/ /destination

Remarquez la fuite /sur la source. Cela signifie qu'il copiera le CONTENU du répertoire et non le répertoire lui-même. Si vous la laissez /désactivée, il copiera toujours les fichiers mais ils se trouveront dans un répertoire nommé /destination/directory. Avec le /, les fichiers seront juste dans/destination

rsyncconservera la propriété des fichiers si vous l'exécutez en tant que root ou si les fichiers vous appartiennent. Il conservera également le mtimefichier de chaque fichier.

UtahJarhead
la source
2
Pour copier un grand dossier d'un disque dur vers un autre disque dur, rsyncsemble tourner en rond mv. Merci pour le conseil!
leo-the-manic
2
tar cf - dir1 | (cd dir2; tar xf -)

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

Lorsque vous utilisez 'cp', chaque fichier fait une ouverture-lecture-fermeture-ouverture-écriture-fermeture. Tar utilise différents processus de lecture et d'écriture ainsi que plusieurs marches pour fonctionner sur plusieurs fichiers à la fois. Même sur un seul boîtier CPU, les applications multithread sont plus rapides.

maholt
la source
2
Bien que cela puisse répondre à la question, ce serait une meilleure réponse si vous pouviez expliquer pourquoi .
DavidPostill
1
S'ils se trouvent sur la machine locale, il est probable qu'ils résident dans le même système de fichiers. En utilisant, tar c | tar xvous obtenez un coût de O (total_size) au lieu de O (file_count).
Raúl Salinas-Monteagudo
1

Comme directory_old et directory_new sont sur le même système de fichiers que vous pourriez utiliser cp -lau lieu de mvcomme option. cp -lcréera un lien dur vers les fichiers d'origine. Lorsque vous avez terminé avec «déplacer» et que vous êtes satisfait du résultat, vous pouvez supprimer ces fichiers de directory_old. en termes de vitesse, ce sera la même chose que «mv» car vous créez d'abord les liens, puis vous supprimez ceux d'origine. Mais cette approche vous permet de recommencer depuis le début si cela a du sens

Serge
la source
0

Cela dépend (tm). Si votre système de fichiers est en copie sur écriture, la copie ( cpou rsync, par exemple) doit être comparable à un déplacement. Mais dans la plupart des cas, move ( mv) sera le plus rapide, car il peut simplement basculer entre les données qui décrivent où un fichier est placé (remarque: cela est trop simplifié).

Donc, sur votre installation Linux moyenne, je choisirais mv.

EDIT: @ Frédéric Hamidi a un bon point dans les commentaires: Ceci n'est valable que s'ils sont tous les deux sur le même système de fichiers et disque. Sinon, les données seront quand même copiées.

carlpett
la source
0

Pour copier au moins ~ 10k de fichiers (pas de répertoires), cp s'est plaint de:

impossible d'exécuter / bin / cp: liste d'arguments trop longue

La meilleure option est Rsync:

cible source rsync

Et cela s'est fait très rapidement!

Nico
la source
0

Si vous disposez de l'espace libre, archivez-les dans un seul fichier .tar (sans compression plus rapide), puis déplacez ce fichier et désarchivez-le.

endolith
la source
0

La nature de la destination déterminerait la manière la plus efficace d'accomplir cette tâche. Supposons que vous êtes sur un système local, le vôtre PWDest /maintenant. et /acontient les millions d'images. Notre tâche consiste à déplacer toutes les images vers /b, tout en conservant toute la structure du sous-répertoire. Supposons également /aet /bsont des points de montage pour deux partitions différentes, chacune sur un disque connecté localement. Nous voudrions faire cette tâche avec une bâche. Cela peut prendre un certain temps, alors assurez-vous d' utiliser screen, tmuxou vous l' exécuter comme un processus d'arrière - plan.

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

Cela copier tous les fichiers et les répertoires /apour /b, maintenant , vous aurez besoin de nettoyer /aune fois que vous le confirmer terminé sans erreur.

JM Becker
la source