bash textes Comment comparer des fichiers avec les mêmes noms dans deux répertoires différents en utilisant un script shell




ubuntu comparer deux fichiers (5)

Avant de passer à SVN, je gérais mon projet en gardant simplement un répertoire /develop/ et en éditant et en testant des fichiers, puis en les déplaçant dans le répertoire /main/ . Quand j'ai décidé de passer à SVN, je devais être sûr que les répertoires étaient bien synchronisés.

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

Remarque: Les noms de répertoire utilisés ci-dessus sont pour l'échantillon seulement. Je ne recommande pas de stocker votre code dans le plus haut niveau :).


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

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


[J'ai lu quelque part que répondre à vos propres questions est OK, alors voilà :)]

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 ne comparer que des fichiers spécifiques [par exemple, seulement les fichiers .php] en éditant la ligne ci-dessus

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

D'autres idées?


diff -rqu /develop /main

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

Si vous voulez voir seulement les nouveaux fichiers / les fichiers manquants

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

Si vous voulez les mettre à nu:

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

voici un exemple de script (un peu désordonné), dircompare.sh , qui va:

  • trier les fichiers et les répertoires dans les tableaux selon le répertoire dans lequel ils se trouvent (ou les deux), en deux passes récursives
  • Les fichiers qui se produisent dans les deux répertoires sont triés à nouveau dans deux tableaux, selon que diff -q détermine s'ils sont différents ou non
  • pour les fichiers dont les diff sont identiques, affichez et comparez les horodatages

J'espère qu'il peut être trouvé utile - Cheers!

EDIT2: ( En fait, cela fonctionne très bien avec les fichiers distants - le problème a été le signal Ctrl-C non géré pendant une opération de comparaison entre le fichier local et le fichier distant, ce qui peut prendre un certain temps. édition précédente ci-dessous pour référence ):

EDIT: ... sauf qu'il semble que mon serveur ~/.gvfs en panne pour un répertoire ssh distant (que j'ai essayé d'utiliser sur ~/.gvfs ) ... Donc ce n'est plus bash , 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/[email protected] testdir1

$ # get earlier example revision 2729 as testdir2
$ svn co https://openbabel.svn.sf.net/svnroot/openbabel/openbabel/trunk/[email protected] 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épertoires dans rsync
  • --dry-run - simule uniquement, ne met 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: affiche un résumé des modifications pour toutes les mises à jour"

Voici un bref extrait de man rsync qui explique les informations montrées par -i (par exemple, les >f.st...... chaînes 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 peu énigmatique, en effet - mais au moins, il montre la comparaison de répertoire de base sur ssh . À votre santé!


Le diff que j'ai disponible permet des différences récursives:

diff -r main develop

Mais avec un script shell:

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




diff