J'ai deux lecteurs avec les mêmes fichiers, mais la structure des répertoires est totalement différente.
Existe-t-il un moyen de "déplacer" tous les fichiers du côté destination afin qu'ils correspondent à la structure du côté source ? Avec un script peut-être ?
Par exemple, le lecteur A a :
/foo/bar/123.txt
/foo/bar/234.txt
/foo/bar/dir/567.txt
Alors que le lecteur B a :
/some/other/path/123.txt
/bar/doo2/wow/234.txt
/bar/doo/567.txt
Les fichiers en question sont énormes (800 Go), donc je ne veux pas les recopier; Je veux juste synchroniser la structure en créant les répertoires nécessaires et en déplaçant les fichiers.
Je pensais à un script récursif qui trouverait chaque fichier source sur la destination, puis le déplacerait dans un répertoire correspondant, en le créant si nécessaire. Mais — c'est au-delà de mes capacités !
Une autre solution élégante a été donnée ici :
https://superuser.com/questions/237387/any-way-to-sync-directory-structure-when-the-files-are-already-on-both-sides /238086
Réponse acceptée :
Je vais aller avec Gilles et vous diriger vers Unison comme suggéré par hasen j. Unison était DropBox 20 ans avant DropBox. Code solide comme le roc que beaucoup de gens (moi y compris) utilisent tous les jours - très intéressant à apprendre. Pourtant, join
a besoin de toute la publicité qu'il peut obtenir 🙂
Ce n'est qu'une demi-réponse, mais je dois me remettre au travail 🙂
Fondamentalement, je voulais démontrer le peu connu join
utilitaire qui fait exactement cela :joint deux tables sur un certain champ.
Tout d'abord, configurez un scénario de test comprenant des noms de fichiers avec des espaces :
for d in a b 'c c'; do mkdir -p "old/$d"; echo $RANDOM > "old/${d}/${d}.txt"; done
cp -r old new
(modifier certains répertoires et/ou noms de fichiers dans new
).
Maintenant, nous voulons construire une carte :hachage -> nom de fichier pour chaque répertoire, puis utiliser join
pour faire correspondre les fichiers avec le même hachage. Pour générer la carte, mettez ce qui suit dans makemap.sh
:
find "$1" -type f -exec md5 -r "{}" ;
| sed "s/([a-z0-9]*) ${1}/(.*)/1 "2"/"
makemap.sh
crache un fichier avec des lignes de la forme, 'hash "filename"', donc nous nous joignons juste sur la première colonne :
join <(./makemap.sh 'old') <(./makemap.sh 'new') >moves.txt
Cela génère moves.txt
qui ressemble à ceci :
49787681dd7fcc685372784915855431 "a/a.txt" "bar/a.txt"
bfdaa3e91029d31610739d552ede0c26 "c c/c c.txt" "c c/c c.txt"
La prochaine étape serait de faire les mouvements, mais mes tentatives se sont bloquées sur la citation… mv -i
et mkdir -p
devrait être utile.