comparer contenu de dossiers

Arlequin

Membre masqué
Club iGen
4 Août 2004
12 255
989
DTC
Bonjour à tous

problème qui me semble être tout bête ! :

lors d'un copie d'un gros dossier (18Go), le réseau à sauté à 90% de la copie :mad:

lorsque je recommence, au lieu de me proposer de ne rajouter que les fichiers manquants, je n'ai le choix que d'annuler ou de tout remplacer !!!! n'ayant pas vraiment envie d'attendre à nouveau aussi longtemps, existe t il dans Tiger, une option pour "comparer" les dossiers......

j'ai déjà regardé du coté de Path Finder et MacExplorer, mais sans succès....

une idée ? avant de passer à un soft de backup......

merci

à +
 
Par le terminal : tu listes le contenu des répertoires dans deux fichiers : "ls > nom_de_ton_fichier" et tu compares les deux fichiers avec la commande "diff" par exemple.
 
ntx a dit:
Par le terminal : tu listes le contenu des répertoires dans deux fichiers : "ls > nom_de_ton_fichier" et tu compares les deux fichiers avec la commande "diff" par exemple.

ce que je voulais dire c'est comparer avant de copier, automatiquement ;)

merci qd même :up:
 
Si tu as installé CarbonCopyCloner, vient avec cet outil une commande en ligne (Terminal) 'psync'. C'est un script en PERL qui fait de la mise à jour, suivant différemment modes (j'écrase tout ou alors je ne copie que ce qu'il faut etc.) C'est très bien.
Comme tu as Tiger, tu peux même l'intégrer à Automator pour en faire une mini appli pratique.

PS : Il existe par défaut sur le système la commande 'rsync' mais elle est beaucoup plus puissante, donc complexe, donc risquée ... ;)
 
bompi a dit:
Si tu as installé CarbonCopyCloner, vient avec cet outil une commande en ligne (Terminal) 'psync'. C'est un script en PERL qui fait de la mise à jour, suivant différemment modes (j'écrase tout ou alors je ne copie que ce qu'il faut etc.) C'est très bien.
Comme tu as Tiger, tu peux même l'intégrer à Automator pour en faire une mini appli pratique.

PS : Il existe par défaut sur le système la commande 'rsync' mais elle est beaucoup plus puissante, donc complexe, donc risquée ... ;)

mais ça ne fonctionne que de disque à disque non ? pas de dossier à dossier ? et encore moi avec un disque réseau il me semble....je vais vérifier.....merci à toi
 
Que nenni ;) Cela se fait de dossier à dossier tout aussi bien.
J'ai même fait pour mes propres besoins un script pour ce genre de chose ...
 
  • J’aime
Réactions: Arlequin
bompi a dit:
Que nenni ;) Cela se fait de dossier à dossier tout aussi bien.
J'ai même fait pour mes propres besoins un script pour ce genre de chose ...

waw, génial, je me mets au test de suite ! un grand merci ! :up: :up: :up:
 
Salut nzadri2

La problématique d'Arlequin, l'auteur de ce fil, était : comment mettre à jour un dossier B contenant 90% de copies d'un dossier A > en évitant de recopier tous les fichiers de a à z de A en mode "écrasement" des fichiers déjà présents dans B ?

La commande rsync (comme indiqué originellement par bompi) peut être utilisée pour opérer une telle mise-à-jour incrémentielle (ne copier que les différences en échappant les identités).

Pour ce faire > on peut passer à l'utilitaire rsync différents types d'options de mise-à-jour :

  • l'option -u (--update) : tous les fichiers sur la destination qui ont un indicateur de temps de modification plus récent que les fichiers correspondant sur la source > seront échappés de recopie (à égalité de temps > le critère d'une égalité de taille sera pris en compte pour permettre l'échappement de recopie) ;
  • l'option -c (--checksum) : tous les fichiers sur la destination qui ont une somme de contrôle identique à ceux de la source seront échappés de recopie ;
  • l'option --size-only : tous les fichiers sur la destination qui ont la même taille que les originaux de la source seront échappés > sans tenir compte des indicateurs de temps ;

Étant supposé que > dans tous les cas d'options ci-dessus > l'option -a (--archive) est toujours présente > qui implique d'opérer récursivement sur tous les éléments de la source qui sont des dossiers > et par ailleurs de préserver tout ce qui compte des propriétés des fichiers source.

L'option -v (--verbose) étant elle aussi toujours ajoutable > afin de permettre une sortie d'affichage à l'écran de chaque élément recopié - cette option a un effet "psychologique" --> rassurer l'utilisateur en lui prouvant par une activité à l'écran qu'il est bien en train de se passer quelque chose plutôt que rien...

En résumé de ce laïus : étant donc donnés 2 dossiers A (source) et B (destination) --> tu peux utiliser la commande concise :
Bloc de code:
rsync -avu /[path]A/* /[path]B
rsync est appelé > avec les 3 options -avu (archive > verbose > update) > l'adresse du dossier A (source) > suivie de /* (signifiant : tenir compte de tous les éléments enfants contenus sans le dossier parent contenant) > l'adresse du dossier B (destination) tout court.

----------

En pratique --> dans la fenêtre du «Terminal» > tu commences par saisir simplement :
Bloc de code:
rsync -avu
et tu sautes un espace avec la barre d'espacement du pointeur. Cela fait > tu fais directement un glisser-déposer du dossier A (source) dans la fenêtre du «Terminal» > ce qui inscrit automatiquement l'adresse au dossier et son nom.

Attention ! ici... Un saut d'espace automatique aura été généré en sortie du glisser-déposer : ramène d'un cran en-arrière la position du pointeur pour annuler cet espace et recoller le point de saisie au dernier caractère du nom de ton dossier A > cela fait > tu saisis manuellement /* à coller ce nom > afin de désigner comme source de la copie non pas le dossier parent mais tous ses contenus (sinon : tu copierais le dossier A dans le dossier B et l'option -u serait perdue avec cette imbrication).

Tu en es donc à quelque chose comme ceci :
Bloc de code:
rsync -avu /[path]A/*
Tu sautes encore un espace avec la barre d'espacement du pointeur > et tu fais carrément un glisser-déposer de ton dossier B (destination) > tu as donc ta commande complète :
Bloc de code:
rsync -avu /[path]A/* /[path]B
Tu n'as plus qu'à presser la touche ↩︎ (= "Entrée") du clavier pour activer la commande.

[Note : rsync construit toujours une liste de ce qu'il faut recopier en fonction des options passées amenant à une comparaison de la source avec la destination. Avec des dossiers (ou des contenus de volumes) énormes > la construction de cette liste préalable peut prendre un temps... certain > avant que l'exécution ne démarre pour de bon.]
 
Pour ceux que la commande rsync rebuterait, un petit script écrit en Python peut la remplacer, avec moins de fonctionnalité mais juste ce qu'il faut pour les besoins de base.

Si la synchronisation doit être régulière, je recommande de faire un script avec les bons paramètres et dossiers sources et destinations, de sorte que l'on n'ait plus qu'à lancer le script sans inquiétude.
Il est tout à fait possible de le faire avec AppleScript ou Automator (il y a dans Automator un composant d'appel de scripts Unix).
 
Merci à tous, j'ai aussi trouvé le logiciel "compare & sync folders" qui m'a permis d'avancer et qui est plus simple visuellement parlant.
 
Bonjour,
J'ai un problème similaire mais encore un peu plus complexe.
J'ai essayé de créer une règle dans hazel, mais on ne peut pas donner comme critère l'existence d'un fichier dans un répertoire.
C'est en cherchant une solution avec rsync que je suis tombé sur votre discussion.
Voici le problème:
J'ai un dossier A qui contient 4 sous dossiers (100apple, 101apple...) qui contient environ 60 000 photos extraites d'un iPhone.
Ces photos ont été déjà importées et classées pour 95% d'entre elles dans plusieurs sous dossiers contenus dans un dossier B.
(Images/images années/ images mois/ lieux...)
Je fais ces imports de photos régulièrement via dropbox mais je ne sais pas pourquoi certaines manquent.
J'ai donc besoin de copier les images de A qui ne soient pas déjà présentes quelquepart dans l'arborescence de B.
J'imaginais faire une liste récursive des fichiers dans A et B, isoler les différences et copier uniquement ces dernières dans un 3eme dossier de résultats pour pouvoir les classer à ma convenance dans B. Et recommencer jusqu'à qu'il n'y ait plus de différence.
Problème supplémentaire, de nombreux fichiers ont déjà été renommés dans B, est-il possible de les identifier dans l'absolu avec le cheksum ou un autre paramètre ?
Merci pour votre aide
Thierry
 
Si certains fichiers ont été renommés, seule l'empreinte numérique de chaque fichier pourra te servir.

Grosso modo, l'idée est de créer un script qui te retourne une liste checksum/<nom complet du fichier> de tous les fichiers présents dans une arborescence, suivant certains critères : tous les fichiers, tous les fichiers de type JPEG, tous les fichiers de type PNG etc.
Tu le passes sur A et sur B et tu compares les deux listes pour savoir quoi faire.

Il y a plein de manières de faire ce genre de chose : cela dépend de tes goûts en matière de scripting (bash, awk, Perl, Python, Ruby, Lua etc.)
Avec bash, tu utiliseras des commandes présentes sur le système (je te conseille plutôt un contrôle avec MD5, suffisant et plus rapide), des outils de tri (uniq, sort), de comparaison etc.
Avec Perl ou Python, il y a des modules pour toutes les fonctions ; en plus, il y a des interfaces pour utiliser SQLite assez simplement. Du coup tu crées une table avec une liste puis une autre avec l'autre liste et en une requête simple tu as les éléments qui t'intéressent.

Il existe aussi sans doute des scripts déjà écrits ;)
 
Salut haverry

Étant donné ton dossier A = "source" > et ton dossier B = "destination" > alors la commande :
Bloc de code:
rsync -avu [PATH]A/* [PATH]B
va uniquement mettre à jour (récursivement) le contenu du dossier B avec les seules différences du dossier A.

En pratique : tu tapes -->
Bloc de code:
rsync -avu
> tu fais un saut d'espace avec la barre d'espacement du clavier > glisser-déposer de A (ne pas se tromper de dossier) > ce qui génère automatiquement un saut d'espace > tu ramènes le pointeur à coller le dernier caractère du nom de A > et tu saisis :
Bloc de code:
/*
> tu sautes un espace > et tu fais un glisser-déposer simple du dossier B. Tu valides avec ↩︎ (touche "Entrée" du clavier).

=> tu dois donc obtenir un dossier B = "destination" complet.

--------------------

En ce qui concerne la gestion des doublons (qui portent des noms différents) > un procédé pourrait être celui-ci -->

Tu installes d'abord le binaire exécutable fdupes. Pour cela > tu vas à : ☞adrianlopezroche/fdupes☜ > tu presses le bouton vert "Clone or download" (à droite) > avec l'option : Download ZIP --> un dossier fdupes-master (une fois dézippé) atterrit à ton emplacement par défaut de téléchargement.

Dans le «Terminal» > tu tapes :
Bloc de code:
cd
> tu sautes un espace > tu fais un glisser-déposer direct du dossier téléchargé fdupes-master dans la fenêtre du «Terminal» et ↩︎ => tu es désormais loggé dans le dossier fdupes-master en tant qu'opérateur du shell.

Tu passes à présent les commandes d'installation du binaire à partir des ressources du dossier (l'une après l'autre) -->
Bloc de code:
make fdupes
su root
make install
(lors de la validation de la seconde = su root --> une demande de password va s'afficher --> tape ton mot-de-passe de session admin à l'aveugle - aucun caractère ne se montrant à la frappe - et valide de nouveau avec ↩︎

=> le binaire fdupes est désormais installé at: /usr/local/bin avec le man à sa place -> manuel que tu peux faire afficher en tapant fdupes dans la fenêtre du «Terminal» > en sélectionnant ce nom > et en faisant un ctrl_clic --> Ouvrir la page de man.

Comme tu es toujours loggé dans le dossier fdupes-master qui ne sert plus à rien (tu peux le benner) > une commande :
Bloc de code:
cd ~/
et ↩︎ te fait récupérer ta localisation par défaut à la racine de ton dossier de compte.

--------------------

Ces petites affres terminées > tu peux utiliser fdupes sur ton dossier B.

La syntaxe de la commande est très simple -->
Bloc de code:
fdupes [OPTIONS] [CIBLE]
fdupes appelle le binaire de /usr/local/bin/fdupes > [OPTIONS] désigne le jeu ad hoc d'options d'après les possibilités listées par le man > [CIBLE] désigne le chemin au dossier à traiter et son intitulé en final.

◉ Si tu veux une liste affichée dans la fenêtre du «Terminal» de tes doublons > tu passes la commande :
Bloc de code:
fdupes -r -o name [PATH]B
et ↩︎

(l'option -r = recursive --> traverser toute la profondeur du répertoire cible > l'option -o appelle un ordre de distribution des doublons trouvés devant être déterminé par un terme > name est le terme = "par nom" choisi ici)

=> en retour tu vas obtenir une liste de tes doublons distribués en § séparés par une ligne vide - chaque § regroupant les variantes du même fichier > avec adresse et nom actuel.

----------​

◉ Si tu veux que la sortie de la commande s'opère sous forme de fichier que tu pourras étudier à tête reposée > voire utiliser pour des suppressions a la mano en cochant les entrées traitées > tu complètes ainsi la commande :
Bloc de code:
fdupes -r -o name [PATH]B > Desktop/doublons.txt
et ↩︎ > et un fichier au format texte doublons.txt va être créé sur ton Bureau au lieu que tu aies une sortie à l'écran.

----------​

◉ Si la consultation de la liste ressortie te donne l'impression que la tâche est titanesque > alors tu peux drastiquement passer la commande :
Bloc de code:
fdupes -rdN [PATH]B

(l'option -r = recursive > est associée à l'option d = delete : supprimer > et à l'option N = No_Prompt : ne pas demander de confirmation)

=> tous les doublons seront supprimés dans l'ordre alphabétique > avec préservation pour chaque grappe de doublons du fichier dont l'intitulé est chaque fois alphabétiquement le premier.

----------​
 
Si tu veux simplement avoir une idée du nombre de fichiers à copier, tu peux taper la commande suivante :
Bloc de code:
diff <(sort <(find /chemin/numero/un -type f -exec md5 -r {} +) | cut -f1 -d ' ') <(sort <(find /chemin/numero/deux -type f -exec md5 -r {} +) | cut -f1 -d ' ')
en remplaçant les deux chemins par les chemins qui te conviennent.

(là, je teste sur Cygwin sur Windows mais ça ne doit pas être loin d'être bon...)

Avec un petit effort, on devrait pouvoir développer ça pour bâtir directement le script à exécuter.
 
Dernière édition:
Petite méthode :
a) on liste les fichiers du dossier A
Bloc de code:
find "/chemin/vers/A" -type f -exec md5 -r {} + | sort > liste_A
b) on liste les fichiers du dossier B
Bloc de code:
find "/chemin/vers/B" -type f -exec md5 -r {} + | sort > liste_B
c) on ne garde que la liste de ceux du dossier A qui n'ont pas été copiés vers le dossier B
Bloc de code:
join -1 1 -v 1 liste_A liste_B > liste_manquants
d) on construit la liste des commandes pour copier les fichiers manquants vers B
Bloc de code:
cat liste_manquants | cut -b 34- | awk '{print "cp \""$0"\" \"/chemin/pour/copie\""}' > copie.sh
e) on exécute la copie des fichiers :
Bloc de code:
sh copie.sh

Ça fonctionne sous Linux (il faut que je redémarre mon Mac pour tester...)

PS : petite vérification toute simple : fort logiquement, en répétant les mêmes commandes, je n'ai plus rien à copier
 
Dernière édition:
Petite explication des commandes :

a) et b)
ce sont les mêmes commandes, avec pour seules différences les noms respectifs des dossiers examinés et ceux des fichiers destinations
On recherche tous les fichiers d'un chemin X et calcule pour chacun sa signature numérique.
On trie les résultats sur la signature numérique (pas forcément utile mais peut aider pour les performances) puis le tout est enregistré dans le fichier "liste_X", sous la forme :
<signature sur 32 caractères> <nom du fichier présent dans X>

c) on liste uniquement les lignes de A pour lesquelles on ne retrouve pas d'équivalent dans B.
Tout simplement, pour chaque ligne de la liste A, on prend son premier élément (la signature) et on le cherche dans la liste B. Si on ne trouve rien, on écrit une ligne dans la liste des manquants.

d) Pour chaque ligne de la liste des manquants, on enlève la signature numérique et on constitue la commande de copie du fichier vers un même répertoire destination.
Là, je pars du principe que l'on copie en vrac.
Si ce n'est pas le cas et que, par exemple, on doit copier dans tel ou tel dossier en fonction de l'emplacement du fichier source, il faudra adapter la ligne, voire la dédoubler.

C'est typiquement unixien : on enchaîne les commandes avec des tuyaux (ou pipe) entre elles, la sortie de l'une devenant l'entrée de la suivante.

e) on a une liste de commandes à exécuter : on la lance.
 
Bonjour

J'ai le problème inverse : je vide une carte de photos RAW sur deux disques : sur le disque travail j'élimine immédiatement les mauvaises. Comment les enlever automatiquement du disque sauvegarde ?