L'approche de la course à pied diff -qr old/ new/
a un inconvénient majeur : il peut manquer des fichiers dans des répertoires nouvellement créés. Par exemple, dans l'exemple ci-dessous, le fichier data/pages/playground/playground.txt
n'est pas dans la sortie de diff -qr old/ new/
alors que le répertoire data/pages/playground/
est (recherche de terrain de jeu.txt dans votre navigateur pour comparer rapidement). J'ai également publié la solution suivante sur Unix et Linux Stack Exchange mais je vais le copier ici aussi :
Pour créer une liste de fichiers nouveaux ou modifiés de manière programmatique, la meilleure solution que j'ai trouvée est d'utiliser la méthode suivante rsync , trier et uniq :
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
Laissez-moi vous expliquer avec cet exemple : nous voulons comparer deux versions de dokuwiki pour voir quels fichiers ont été modifiés et lesquels ont été nouvellement créés.
Nous récupérons les tars avec wget et les extrayons dans les répertoires suivants old/
et new/
:
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29d.tgz
wget http://download.dokuwiki.org/src/dokuwiki/dokuwiki-2014-09-29.tgz
mkdir old && tar xzf dokuwiki-2014-09-29.tgz -C old --strip-components=1
mkdir new && tar xzf dokuwiki-2014-09-29d.tgz -C new --strip-components=1
L'exécution de rsync d'une manière ou d'une autre peut manquer des fichiers nouvellement créés comme le montre la comparaison de rsync et diff ici :
rsync -rcn --out-format="%n" old/ new/
donne le résultat suivant :
VERSION
doku.php
conf/mime.conf
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
En exécutant rsync dans un seul sens, les fichiers nouvellement créés ne sont pas pris en compte et dans l'autre sens, les fichiers supprimés ne sont pas pris en compte, comparez la sortie de diff :
diff -qr old/ new/
donne le résultat suivant :
Files old/VERSION and new/VERSION differ
Files old/conf/mime.conf and new/conf/mime.conf differ
Only in new/data/pages: playground
Files old/doku.php and new/doku.php differ
Files old/inc/auth.php and new/inc/auth.php differ
Files old/inc/lang/no/lang.php and new/inc/lang/no/lang.php differ
Files old/lib/plugins/acl/remote.php and new/lib/plugins/acl/remote.php differ
Files old/lib/plugins/authplain/auth.php and new/lib/plugins/authplain/auth.php differ
Files old/lib/plugins/usermanager/admin.php and new/lib/plugins/usermanager/admin.php differ
L'exécution de rsync dans les deux sens et le tri de la sortie pour supprimer les doublons révèle que le répertoire data/pages/playground/
et le fichier data/pages/playground/playground.txt
ont été manquées au départ :
(rsync -rcn --out-format="%n" old/ new/ && rsync -rcn --out-format="%n" new/ old/) | sort | uniq
donne le résultat suivant :
VERSION
conf/mime.conf
data/pages/playground/
data/pages/playground/playground.txt
doku.php
inc/auth.php
inc/lang/no/lang.php
lib/plugins/acl/remote.php
lib/plugins/authplain/auth.php
lib/plugins/usermanager/admin.php
rsync
est exécuté avec ces arguments :
-
-r
pour "récurer dans les répertoires",
-
-c
pour comparer également des fichiers de taille identique et seulement "sauter en fonction de la somme de contrôle, et non du temps de modulation et de la taille",
-
-n
pour "effectuer un essai sans modification", et
-
--out-format="%n"
pour "sortir les mises à jour en utilisant le FORMAT spécifié", qui est "%n" ici pour le nom du fichier seulement.
La sortie (liste de fichiers) de rsync
dans les deux sens est combiné et trié en utilisant sort
et cette liste triée est ensuite condensée en supprimant tous les doublons à l'aide de la commande uniq