Comment comparer des fichiers portant le même nom dans deux répertoires différents à l'aide d'un script shell

StackOverflow https://stackoverflow.com/questions/119788

  •  02-07-2019
  •  | 
  •  

Question

Avant de passer à l’utilisation de SVN, j’avais l'habitude de gérer mon projet en conservant simplement un répertoire / develop / , en y modifiant et en testant les fichiers, puis en les déplaçant vers le / main / répertoire. Lorsque j'ai décidé de passer à SVN, je devais m'assurer que les répertoires étaient bien synchronisés.

Alors, quel est le bon moyen d'écrire un script shell [bash] pour comparer de manière récursive des fichiers portant le même nom dans deux répertoires différents?

Remarque: les noms de répertoire utilisés ci-dessus ne sont donnés qu'à titre d'exemple. Je ne recommande pas de stocker votre code dans le niveau supérieur:).

Était-ce utile?

La solution

La commande diff a une option -r pour comparer de manière récursive les répertoires:

diff -r /develop /main

Autres conseils

diff -rqu /develop /main

Cela ne vous donnera qu'un résumé des modifications de cette façon :)

Si vous voulez voir uniquement les nouveaux / manquants fichiers

diff -rqu /develop /main | grep "^Only

Si vous voulez les mettre à nu:

diff -rqu /develop /main | sed -rn "/^Only/s/^Only in (.+?): /\1/p"

Le diff dont je dispose permet des différences récursives:

diff -r main develop

Mais avec un script shell:

( cd main ; find . -type f -exec diff {} ../develop/{} ';' )

[J'ai lu quelque part que le fait de répondre à vos propres questions est correct, alors voici :)]

J'ai essayé ça, et ça a plutôt bien marché

[/]$ cd /develop/
[/develop/]$ find | while read line; do diff -ruN "/main/$line" $line; done |less

Vous pouvez choisir de comparer uniquement des fichiers spécifiques [par exemple, uniquement les fichiers .php] en modifiant la ligne ci-dessus comme

.
[/]$ cd /develop/
[/develop/]$ find -name "*.php" | while read line; do diff -ruN "/main/$line" $line; done |less

Avez-vous d'autres idées?

voici un exemple de script (un peu compliqué), dircompare.sh , ce qui:

  • trie les fichiers et les répertoires dans les tableaux en fonction du répertoire dans lequel ils apparaissent (ou les deux), en deux passes récursives
  • Les fichiers présents dans les deux répertoires sont à nouveau triés dans deux tableaux, selon que diff -q détermine s'ils diffèrent ou non
  • pour les fichiers revendiqués par diff , les horodatages d'affichage et de comparaison sont identiques

J'espère que cela pourra être utile - à la vôtre!

EDIT2: ( En fait, cela fonctionne très bien avec les fichiers distants - le problème était un signal Ctrl-C non géré lors d'une opération de diff entre un fichier local et un fichier distant, ce qui peut prendre un certain temps; le script est maintenant mis à jour avec une interruption pour gérer que - cependant, en laissant l'édition précédente ci-dessous pour référence ):

EDIT: ... sauf que mon serveur semble planter pour un répertoire ssh distant (que j'ai essayé d'utiliser sur ~ / .gvfs ) ... Donc, ce n'est pas bash plus, mais une alternative est d'utiliser rsync , voici un exemple:

$ # get example revision 4527 as testdir1
$ svn co https://openbabel.svn.sf.net/svnroot/openbabel/openbabel/trunk/data@4527 testdir1

$ # get earlier example revision 2729 as testdir2
$ svn co https://openbabel.svn.sf.net/svnroot/openbabel/openbabel/trunk/data@2729 testdir2

$ # use rsync to generate a list 
$ rsync -ivr --times --cvs-exclude --dry-run testdir1/ testdir2/
sending incremental file list
.d..t...... ./
>f.st...... CMakeLists.txt
>f.st...... MACCS.txt
>f..t...... SMARTS_InteLigand.txt
...
>f.st...... atomtyp.txt
>f+++++++++ babel_povray3.inc
>f.st...... bin2hex.pl
>f.st...... bondtyp.h
>f..t...... bondtyp.txt
...

Notez que:

  • Pour obtenir ce qui précède, vous ne devez pas oublier les barres obliques / à la fin des noms de répertoire dans rsync
  • - exécution à sec - simuler uniquement, ne mettez pas à jour / transfère les fichiers
  • -r - recurse dans les répertoires
  • -v - verbose (mais pas lié ??aux informations sur les modifications de fichiers)
  • - cvs-exclude - ignore les fichiers .svn
  • -i - "- itemize-changes: génère un récapitulatif des modifications pour toutes les mises à jour "

Voici un bref extrait de man rsync qui explique les informations affichées par -i (par exemple, le > f.st .... .. ci-dessus):

The  "%i"  escape  has a cryptic output that is 11 letters long.
The general format is like the string YXcstpoguax,  where  Y  is
replaced  by the type of update being done, X is replaced by the
file-type, and the other letters represent attributes  that  may
be output if they are being modified.

The update types that replace the Y are as follows:

o      A  < means that a file is being transferred to the remote
       host (sent).

o      A > means that a file is being transferred to  the  local
       host (received).

o      A  c  means that a local change/creation is occurring for
       the item (such as the creation  of  a  directory  or  the
       changing of a symlink, etc.).

...
The file-types that replace the X are: f for a file, a d  for  a
directory,  an  L for a symlink, a D for a device, and a S for a
special file (e.g. named sockets and fifos).

The other letters in the string above  are  the  actual  letters
that  will be output if the associated attribute for the item is
being updated or a "." for no change.  Three exceptions to  this
are:  (1)  a newly created item replaces each letter with a "+",
(2) an identical item replaces the dots with spaces, and (3)  an
....

Un bit cryptique, certes - mais au moins, il montre une comparaison de répertoire de base sur ssh . À la vôtre!

La réponse classique (System V Unix) serait dircmp dir1 dir2 , qui était un script shell qui listerait les fichiers trouvés dans dir1 mais pas dir2 ni dans dir2 mais pas dir1 au début ( première page de sortie, à partir de la commande pr , ainsi paginée avec des en-têtes), suivie d'une comparaison de chaque fichier commun avec une analyse (le même, différent, répertoire étaient les résultats les plus communs).

Cela semble être en train de disparaître - j'ai une réimplémentation indépendante disponible si vous en avez besoin. Ce n’est pas sorcier ( cmp est votre ami).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top