web-dev-qa-db-fra.com

Utilitaire de déplacement récursif sur UNIX?

Parfois, j'ai deux arbres qui avaient l'habitude d'avoir le même contenu, mais sont devenus de la synchronisation (parce que j'ai déplacé des disques autour ou peu importe). Un bon exemple est un arbre où je reflète des forfaits en amont de Fedora.

Je veux encore fusionner ces deux arbres en déplaçant tous les fichiers d'arbre1 en arbre2.

Habituellement, je fais cela avec:

rsync -arv tree1/* tree2

Puis supprimez Tree1.

Cependant, cela prend énormément de temps et d'espace disque, et il serait beaucoup plus facile de pouvoir faire:

mv -r tree1/* tree2

En d'autres termes, un mouvement récursif. Ce serait plus rapide parce que tout d'abord, il ne serait même pas copié, déplacez simplement les inodes et, deuxième, je n'aurais pas besoin d'une suppression à la fin.

Est-ce qu'il existe?

En tant que cas d'essai, considérez la séquence de commandes suivante:

$ mkdir -p a/b
$ touch a/b/c1
$ rsync -arv a/ a2
sending incremental file list
created directory
./
b/
b/c1
b/c2

sent 173 bytes  received 57 bytes  460.00 bytes/sec
total size is 0  speedup is 0.00
$ touch a/b/c2

Quelle commande aurait désormais l'effet de déplacer A/B/C2 à A2/B/C2, puis supprimant le sous-arbre (puisque tout est déjà dans l'arborescence de destination)?

6

Per le MV (1) Manpage de GNU's mv:

-u, --update move only when the SOURCE file is newer than the destination file or when the destination file is missing

2
Bill B

la proposition mv -uf dir1/* dir2/ Déplacez les annuaires (sous), pas chaque fichier. Vous pourriez essayer d'utiliser find

cd dir1
find . -type d -exec mkdir -p dir2/"{}" \;
find . -type f -exec mv -uf "{}" dir2/"{}" \;

ou quelque chose de similaire

2
Javier

Ne fait pas

mv -uf tree1/* tree2/

travail?

1
David Spillett

La réponse de Javier avec Trouver fonctionne bien, sauf qu'il ne retire pas les répertoires d'origine. Ajouter à la fin:

rmdir $(find . -type d  |grep -v ^\.$)
1
Howie Goodell

se tromper

mv dir1/* dir2/

ou simplement

rsync -arv --remove-source-files  tree1/* tree2

devrait suffire, vous risquerrez probablement des ennuis à un moment donné lorsque trop d'entrées sont en dir1.

find sourcedir -maxdepth 1 -exec echo mv {} targetdir/ \;

devrait être une belle options

find sourcedir -maxdepth 1 -print0 |xargs -0 -I _ echo mv _ targetdir
find sourcedir -maxdepth1 -exec mv {} targetdir/ +

les deux ne sont pas vraiment nécessaires car MV prend juste 2 options (cible de source), vous devrez donc vivre avec la multitude de processus dans ce cas.

0
serverhorror

Je pense que MV ne fait pas ce que vous pensez.

Un système de fichiers UNIX a 3 composants:

  • entrées d'annuaire
  • inodes
  • blocs

Une entrée de répertoire pointe vers une inode.

L'inode a la métatadata sur le fichier (est-ce un fichier, un répertoire, un tuyau nommé? Qui le possède? Quelles sont les autorisations? Quels blocs cet inode utilise-t-il?

Les blocs sont les choses qui contiennent réellement le contenu du fichier.

Ainsi, lorsque vous "MV", un fichier, tout ce que vous faites vraiment est de dissuader la première saisie de répertoire et de le réinitialiser ailleurs.

snoopy -> inode 333 
woodstock -> inode 333

Aucune donnée n'est jamais dupliquée/copiée. Vous créez le lien Snoopy, puis vous créez le lien Woodstock, puis vous supprimez le lien Snoopy. (Les choses sont un peu différentes avec des répertoires car, généralement, vous ne pouvez généralement pas faire des répertoires rigides, mais même le nom "link" change simplement).

Et si vous passez d'un système de fichiers à un autre? Au cours des anciens jours, MV viennerait une erreur et le rendrait explicite que vous ne pouvez pas déplacer un fichier d'un système de fichiers à un autre. Ces jours-ci, il semble que mv silencieusement copies Les données supprime ensuite l'original.

Dans les vieux jours, parce que vous ne pouviez pas déplacer des données d'un système de fichiers à un autre, vous avez l'habitude d'utiliser des idiomes comme

tar -cf -. | (CD/NOUVEAU/LOCATION && TAR -XF -)

ensuite, vous supprimez les anciennes données. Une partie de la raison de l'utilisation de goudron était que, dans l'ancien temps, CP détruirait des métadonnées comme "Ceci est un lien symbolique" et "c'est un lien dur" et que vous obtiendrez plutôt de nouvelles copies de ce fichier en tant que fichiers réguliers. Même toujours, vous devez donner des drapeaux "CP" pour lui dire de préserver ce type de structure.

Il n'ya aucun moyen d'éviter de "déplacer" de nombreuses données s'il s'agit d'un système de fichiers à un autre. Peu importe que vous utilisiez un nouveau mouvement de fantaisie ou RSYNC ou TAR ou CPIO.

Mais si vous gardez toutes les données dans le même système de fichiers, ceci:

mV/System-1/Big/Répertoire */FileSystem-1/Big2 /

cela sera extrêmement rapide car il s'agit simplement de modifier les entrées de répertoire et de ne pas déplacer toutes les données réelles.

Il existe d'autres problèmes en jeu, tels que ce que vous devriez faire s'il existe déjà un fichier/répertoire dans le nouvel emplacement ainsi que l'emplacement de la source?

0
chris