GNU/Linux >> Tutoriels Linux >  >> Linux

Un moyen de synchroniser la structure des répertoires lorsque les fichiers sont déjà des deux côtés ?

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.

Connexe :comment regrouper tous les fichiers cachés, à l'exception du répertoire actuel et du répertoire parent ?
Linux
  1. Comment changer l'extension de plusieurs fichiers ?

  2. Fichiers Cat avec répertoire ?

  3. Moyen rapide d'inclure un chemin de répertoire lors de l'appel de Mv ? ?

  4. Le moyen le plus rapide d'extraire un iso ?

  5. Façon de dire à Logrotate d'ignorer les fichiers ouverts ?

Quelles sont les différences entre les fichiers Linux et Windows .txt (encodage Unicode)

Où est le répertoire temporaire sous Linux ?

Lorsque vous effectuez apt-get install, où sont stockés les fichiers .deb ?

Quelle est la manière la plus efficace de déplacer un grand nombre de fichiers qui résident dans un seul répertoire ?

Quel est le moyen le plus rapide de supprimer tous les fichiers et sous-dossiers d'un répertoire ?

Quelles sont les implications en termes de performances pour des millions de fichiers dans un système de fichiers moderne ?