1 votes

md5sum des fichiers dans deux dossiers

J'essaie de comparer tous les fichiers de deux dossiers via un md5sum en une seule commande. Un peu comme ce qui suit (bash) dans Debian :

$ cd ~/FOLDER1
$ md5sum ~/FOLDER2/* | md5sum -c -

L'idée est que la sortie des hachages du premier md5sum sera passée dans le second et utilisée comme fichier d'entrée. Cependant, les tests effectués montrent qu'il ne fait que comparer chaque fichier de FOLDER2 à lui-même et renvoie "OK" pour chacun d'entre eux. Je pense que la raison pour laquelle cela ne fonctionne pas est que les noms de fichiers générés par le premier md5sum incluent le chemin complet. J'ai regardé md5deep mais je n'ai rien trouvé pour m'y aider. Je sais qu'il est possible de faire le md5sum pour un dossier, d'écrire les résultats dans un fichier, puis d'utiliser ce fichier comme entrée pour le second md5sum. Je voulais faire tout cela en une seule ligne par le biais d'un pipe, plutôt que d'utiliser deux commandes et d'écrire un fichier.

Edit : La réponse acceptée ici (en utilisant diff ) pourrait faire ce que je veux, mais je ne sais pas si diff (correctement) compare des fichiers binaires.

Edit : Pour obtenir la sortie que je voulais en utilisant md5sum (qui montre le nom du fichier et "OK"), j'ai eu recours à l'écriture d'un fichier batch. Exécuter avec diffFolders.sh ~/FOLDER1 ~/FOLDER2 .

#!/bin/bash
HERE=$PWD
cd "$1"
md5sum * > /tmp/md5sum.cmp
cd "$2"
md5sum -c /tmp/md5sum.cmp
cd $HERE

Ce script comparera seulement les fichiers qui sont présents dans ~/FOLDER . Si ~/FOLDER2 a des fichiers supplémentaires, ceux-ci ne seront pas comparés et aucune sortie n'indiquera qu'ils existent.

2voto

cyphun Points 15

Vous pouvez utiliser substitution de processus pour passer la sortie des 2 md5sum's à diff. Diff, dans ce cas, serait parfait car les sorties md5 sont en texte clair. Quelque chose comme :

diff <(md5 ~/FOLDER1/* | awk '{print $4}') <(md5 ~/FOLDER2/* | awk '{print $4}')

Désolé, je n'ai pas Debian ici et je ne peux pas tester cela sur elle. Ce qui précède a été testé sur OS X qui a md5, ce qui peut être légèrement différent en termes de résultats. Sous OS X, la 4e colonne de md5 est la somme réelle de md5, c'est pourquoi je ne prends que ces colonnes.

Au lieu de l'awk, vous pouvez également utiliser cut mais vous devrez peut-être changer le séparateur pour obtenir la quatrième colonne (ces colonnes ne sont pas séparées par des tabulations).

0voto

a_lurker Points 11

Un peu long mais renvoie le nom du fichier et OK s'ils correspondent. Au lieu d'utiliser '-c', il s'agit juste de comparer les deux chaînes de caractères résultant de l'exécution de md5sum sur le fichier dans chaque dossier.

for f in *; do [[ -f $f ]] && if [ $(md5sum "$f" | cut -d" " -f1) == $(md5sum dir2/"$f" | cut -d" " -f1) ]; then echo "$f" "OK"; else echo "$f" "MODIFIED"; fi; done

0voto

GreenFox Points 151

De mon fichier .bashrc.
très vieux trucs il devrait être possible d'écrire dans un code beaucoup plus facile à trier. Je n'ai jamais eu l'occasion de le réécrire. (comme tout ce qui était destiné à une solution temporaire, utilisé pour toujours). Je poste ce bout de code honteux, en espérant que quelqu'un pourra le faire mieux et poster le résultat :-)

Caractéristiques :

  • Récupération transversale
  • vérification de l'unicité/différence du md5sum
  • Liste des fichiers mis à jour dans le chemin complet

Le code dit tout. arg1 est l'ancien répertoire, arg2 est le nouveau répertoire.

function find-updated-files-between-old-new(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( ( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n")
 )|sort -k1.2|tee 1>/dev/null >(uniq -us1|awk -v B="$2" 'BEGIN{sub("/$",""B)}/^-/{print B substr($0,3);
 }') >(uniq -ds1|awk -vA="$1" -vB="$2" 'BEGIN{B=g(B);A=g(A)}{
 C=substr($0,3);if(f(A)!=f(B))print B C;}function g(y){sub("/$","",y);return y}
 function f(y,z,e){e="md5sum \""y""C"\"";e|getline z;close(e);return substr(z,1,32)}' )
 ) | cat
}

Comme le nom de la fonction l'indique

function find-files-name-collision-between-dir1dir2(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." > /dev/stderr && return 1;
( cat <(cd "$1";find . -type f -printf "+%p\n") <(cd "$2";find . -type f -printf "-%p\n") )|sort -k 1.2 | uniq -d -s 1
}

Juste pour être complet

function mv-mergedir1todir2(){
 [ ! -d "$1" ] || [ ! -d "$2" ] && echo "*** Error: The directory is not found." && return 1;
 ( cd "$1" ; tar cf - . ) | (cd "$2" ; tar --keep-old-files xvf - )
 echo -e "Done. Duplicate filnames are not replaced. \n#Use \n# ( cd \"$1\" ; tar cf - . ) | (cd \"$2\" ; tar --overwrite xvf - ) \n#if you do not like that. "
}

Cet affreux morceau de code devrait être supprimé de mon bashrc, mais il est là depuis longtemps...

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X