2008-09-23 31 views
18

Antes de pasar a usar SVN, solía administrar mi proyecto simplemente manteniendo un directorio /develop/ y editando y probando archivos allí, luego moviéndolos al /main/ directorio. Cuando decidí cambiarme a SVN, necesitaba estar seguro de que los directorios estaban realmente sincronizados.Cómo comparar archivos con los mismos nombres en dos directorios diferentes usando un script de shell

Entonces, ¿cuál es una buena manera de escribir un script de shell [bash] para comparar recursivamente los archivos con el mismo nombre en dos directorios diferentes?

Nota: Los nombres de directorio utilizados anteriormente son sólo para muestra. No recomiendo almacenar tu código en el nivel superior :).

Respuesta

26

El comando diff tiene una opción -r para comparar de forma recursiva directorios:

diff -r /develop /main 
+0

No técnicamente bash, pero una mejor solución si su diff lo admite. – paxdiablo

+4

¡Funciona para mí! Gracias. Además, para una impresión más bonita, diff -ru/develop/main también funciona – Animesh

1

[He leído en alguna parte que responder a sus propias preguntas está bien, así que aquí va :)]

He intentado esto, y funcionó bastante bien

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

Usted puede elegir para comparar sólo los archivos específicos [por ejemplo, sólo los que php] mediante la edición de la línea anterior como

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

¿Alguna otra idea?

4

El diff que tengo disponible permite diferencias recursivas:

diff -r main develop 

pero con un script de shell:

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

Sólo se le dará un resumen de los cambios de esa manera :)

Si desea ver solo nuevo/falta archivos

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

Si usted quiere conseguirlos desnudo:

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

Esto funciona pero está truncando el último directorio "slash" como por ejemplo: el resultado abc/def/ghi se muestra como abc/defghi – iaav

0

El (Unix System V) respuesta clásica sería dircmp dir1 dir2, que era un script de shell que listar los archivos que se encuentran en cualquiera de dir1 pero no Dir2 o en dir2 pero no dir1 al inicio (primera página de salida, desde el comando pr, así paginado con encabezados), seguido de una comparación de cada archivo común con un análisis (el mismo directorio fue el más común).

Esto parece estar en el proceso de desaparecer, tengo una reimplementación independiente disponible si lo necesita. No es ciencia de cohetes (cmp es tu amigo).

1

aquí es un ejemplo de un guión (algo desordenado) de la mina, dircompare.sh, que serán:

  • Ordenar archivos y directorios en las matrices en función de qué directorio se producen en (o ambos), en dos recursiva
  • pasa
  • Los archivos que se producen en ambos directorios, se ordenan de nuevo en dos matrices, dependiendo de si diff -q determina si difieren o no
  • para aquellos archivos que diff reclamaciones son iguales, mostrar y comparar las marcas de tiempo

Espero que lo encuentren útil - ¡Salud!

EDIT2: (En realidad, funciona bien con archivos remotos: el problema no fue controlado Ctrl-C señal durante una operación diff entre archivos locales y remotos, que puede llevar un tiempo; script actualizado con una trampa para manejar eso - sin embargo, dejando a la edición anterior a continuación como referencia):

eDIT: ... excepto que parece chocar mi servidor para un directorio ssh remoto (que he intentado usar más de ~/.gvfs) ... Así que esto no es bash más, pero una alternativa que supongo es usar rsync, he aquí un ejemplo:

$ # 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 
... 

Tenga en cuenta que:

  • Para conseguir lo anterior, no hay que olvidar barra final / al final de los nombres de directorio en rsync
  • --dry-run - simular solamente, no se actualizan los archivos de transferencia/
  • -r - Recursividad en directorios
  • -v - verbose (pero no presentar información relacionada con los cambios)
  • --cvs-exclude - ignorar .svn archivos
  • -i - "-cambios --itemize: salida de un cambio-resumida de todos los cambios"

que aquí hay una breve extracto de man rsync que explica la información mostrada por -i (por ejemplo, , las cadenas >f.st...... anteriores):

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 poco críptico, de hecho, pero al menos muestra una comparación básica de directorios sobre ssh. ¡Aclamaciones!

Cuestiones relacionadas