Dados dos árboles de directorios, ¿cómo puedo saber qué archivos difieren según el contenido?

786

Si quiero encontrar las diferencias entre dos árboles de directorios, generalmente solo ejecuto:

diff -r dir1/ dir2/

Esto genera exactamente cuáles son las diferencias entre los archivos correspondientes. Estoy interesado en obtener una lista de los archivos correspondientes cuyo contenido difiere. Supuse que esto sería simplemente una cuestión de pasarle una opción de línea de comando diff, pero no pude encontrar nada en la página del manual.

¿Alguna sugerencia?

Mansoor Siddiqui
fuente
1
Con respecto a uno de los directorios, ¿cómo obtener solo los archivos / directorios que son adicionales en el otro?
Sandeepan Nath
use el dircmpcomando en Unix (no Linux)
roblogic

Respuestas:

1119

Usted dijo Linux, así que tuvo suerte (al menos debería estar disponible, no estoy seguro de cuándo se agregó):

diff --brief --recursive dir1/ dir2/ # GNU long options
diff -qr dir1/ dir2/ # common short options

Debería hacer lo que necesita.

Si también desea ver diferencias para archivos que pueden no existir en ninguno de los directorios:

diff --brief --recursive --new-file dir1/ dir2/ # GNU long options
diff -qrN dir1/ dir2/ # common short options
Mark Loeser
fuente
12
Agradable. Pero es más corto diff -qr dir1/ dir2/y mi versión extendida adiff -qr dir1/ dir2/ | grep ' differ'
sobi3ch
1
@skv ¿por qué? Es el mismo comando que la respuesta. Solo he cambiado --briefa su acceso directo -q.
sobi3ch
2
@skv No es exactamente lo que preguntó la pregunta original, pero también actualizo la respuesta para acomodar esta pregunta.
Mark Loeser
3
@MikeMaxwell Tiene que ser así --brief. -briefse interpreta como -b -r -i -e -f, en otras palabras, como un conjunto de banderas, no como una sola opción.
daboross
2
@daboross: wow, he estado usando Unix / Linux durante mucho tiempo, y nunca me di cuenta de que había una distinción entre '-' y '-'. (No creo que existiera '-' cuando comencé.) ¡Gracias por la explicación!
Mike Maxwell
287

El comando que uso es:

diff -qr dir1/ dir2/

Es exactamente lo mismo que Mark :) Pero su respuesta me molestó, ya que usa diferentes tipos de banderas, y me hizo mirar dos veces. Usando las banderas más detalladas de Mark sería:

diff  --brief --recursive dir1/ dir2/

Pido disculpas por publicar cuando la otra respuesta es perfectamente aceptable. No pude detenerme ... trabajando en ser menos pedante.

FPC
fuente
3
aprecio totalmente la consistencia, pero no te sientas mal; También he votado a favor de la respuesta de Mark;)
Gerard ONeill
10
¿Entonces tiene sentido poner respuestas diferentes con SOLO un sabor diferente? En mi humilde opinión no! ¿Tiene sentido combinar ambas respuestas en una respuesta consistente? ¡si! ;)
sobi3ch
1
Sólo una pregunta; ¿Qué significa el qsoporte? ¿Es una abreviatura de algo? No puedo encontrar ninguna lógica detrás del q..
kramer65
3
@ kramer65 - es lo mismo que "- breve", pero supongo que te preguntas por qué q? Quizás por rápido? "-b" se toma como "ignorar cambios en la cantidad de espacio en blanco" según la página del manual.
FPC
44
@ kramer65 Creo que qes para quiet, generalmente significa menos detallado.
Gogeta70
105

Me gusta usar git diff --no-index dir1/ dir2/, porque puede mostrar las diferencias de color (si tiene esa opción establecida en su configuración de git) y porque muestra todas las diferencias en una salida paginada larga usando "menos".

Alan Porter
fuente
25
Ordenado. ¿Quién hubiera adivinado que git puede diferenciar directorios arbitrarios, no solo el repositorio contra sus archivos?
Dan Dascalescu
2
Perl script colordiff es muy útil aquí, se puede usar con svn y diff normal.
Felipe Alvarez
44
Si compara (como yo) 2 directorios como proyectos / repos de git separados, entonces necesita agregar --no-indexmás en stackoverflow.com/a/1792477/473390 . He actualizado la respuesta de @ alan-porter.
sobi3ch
Me gusta este, también encuentro que si agrega --name-status a la línea de comando, solo mostrará la lista de nombres de archivo con banderas "M / A / D" para el estado Modificado / Agregado / Eliminado.
Gzh
Ocurre para que ambos directorios contengan la carpeta .git, ¿cómo puedo excluirla de la comparación?
Muhamed Cicak
35

Estos dos comandos hacen básicamente lo que se solicita:

diff --brief --recursive --no-dereference --new-file --no-ignore-file-name-case /dir1 /dir2 > dirdiff_1.txt

rsync --recursive --delete --links --checksum --verbose --dry-run /dir1/ /dir2/ > dirdiff_2.txt

La elección entre ellos depende de la ubicación de dir1 y dir2:

Cuando los directorios residen en dos unidades separadas, diff supera a rsync. Pero cuando los dos directorios comparados están en la misma unidad, rsync es más rápido. Es porque diff pone una carga casi igual en ambos directorios en paralelo, maximizando la carga en las dos unidades.

rsync calcula las sumas de verificación en fragmentos grandes antes de compararlas realmente. Eso agrupa las operaciones de E / S en grandes fragmentos y conduce a un procesamiento más eficiente cuando las cosas tienen lugar en una sola unidad.

CodeBug
fuente
3
rsync no solo es más rápido para archivos en unidades individuales, sino que también permite comparar archivos en subdirectorios, por ejemplo rsync --options /usr /bin /var /sbin /lib /old_root, comparará efectivamente la raíz actual /(especificando todos los subdirectorios) y /old_root(que contiene, por ejemplo, alguna copia de seguridad anterior /), que es algo que diff -rpuede No lo hagas. Y si asume que los archivos con el mismo tamaño, permisos y marcas de tiempo probablemente no hayan cambiado, la omisión --checksumle proporcionará una verificación extremadamente rápida (si no es así) de qué archivos podrían haber cambiado.
Matija Nalis
1
¿Cuál es el propósito de --deletecon rsync?
Tom Hale
2
El propósito de --delete es eliminar los archivos existentes en el directorio de destino que ya no están presentes en el directorio de origen
Thomas Munk
2
En este caso (con la --dry-runbandera), nada se elimina realmente, rsyncsolo imprime qué archivos están en dir1 pero no en dir2
mata
11
Recomiendo poner --dry-runprimero siempre para no olvidarlo accidentalmente.
Dave Rager
22

Meld también es una gran herramienta para comparar dos directorios:

meld dir1/ dir2/

Meld tiene muchas opciones para comparar archivos o directorios. Si dos archivos difieren, es fácil ingresar al modo de comparación de archivos y ver las diferencias exactas.

Alejandro
fuente
2
Agradable. He escrito una secuencia de comandos perl simple para realizar una comparación sobre árboles, pero estoy llegando a limitaciones. Este parece ser el boleto.
David Tonhofer
El único problema es que no se presta a las secuencias de comandos, ya que es una aplicación gráfica. ¡Pero es bueno si no te importa la GUI! Gracias.
DeanM
Sin meldembargo, creo que se vuelve terriblemente lento si se usa en directorios grandes. ¿Hay algo que maneje mejor los directorios grandes?
Popup
@ Popup, no que yo sepa. Sin embargo, podría encontrar diferentes nombres de archivo con algo como esto:find dir1 dir2 | cut -d/ -f2- | sort | uniq --unique
Alexander
1
@Alexander: en ese caso, creo que meld <(find dir1 -ls ) <(find dir2 -ls)funciona bastante bien, utilizando la sustitución del proceso bash. (zsh's =(command)funciona aún mejor.)
Popup
10

Compatriotas del canal 'billings' (de freenode / # centos fame) compartió su método conmigo:

diff -Naur dir1/ dir2

Incluir la barra diagonal final del directorio no importa.

Además, parece que la -uopción no está disponible en algunas versiones anteriores / servidor de diff.

La diferencia en diffs:

# diff -Nar /tmp/dir1 /tmp/dir2/
diff -Nar /tmp/dir1/file /tmp/dir2/file
28a29
> TEST

# diff -qr /tmp/dir1/ /tmp/dir2/
Files /tmp/dir1/file and /tmp/dir2/file differ
todd_dsm
fuente
2
Eso es lo --new-file/-Nque hace que diff considere que los archivos faltantes están vacíos y --text/-aque considera que todas las entradas binarias son texto. No veo las ventajas de este caso de uso en particular.
phk
4

Difoscopio es una gran herramienta de diferencia de directorios basada en la línea de comandos.

Me gusta especialmente que pueda diferir en archivos:

Descomprimirá de manera recursiva archivos de muchos tipos y transformará varios formatos binarios en una forma más legible para humanos para compararlos. Puede comparar dos tarballs, imágenes ISO o PDF con la misma facilidad.

No solo le dirá qué archivos difieren, sino también cómo difieren.

nh2
fuente
4

Para encontrar diff, use este comando:

diff -qr dir1/ dir2/

-r también diferirá todos los subdirectorios -q le dice a diff que informe solo cuando los archivos difieran.

diff  --brief dir1/ dir2/

- breve mostrará los archivos que no existen en el directorio.

Si no

Podemos usar Meld, que mostrará en una ventana gráfica que es fácil encontrar la diferencia.

meld  dir1/ dir2/
Javeed Shakeel
fuente
2
--briefY -qson la misma opción. Su declaración hace que parezca que son diferentes pero no lo son.
Elijah Lynn
2

Puede también usar Rsyncy find. Para find:

find $FOLDER -type f | cut -d/ -f2- | sort > /tmp/file_list_$FOLDER

Pero los archivos con los mismos nombres y en las mismas subcarpetas, pero con contenido diferente, no se mostrarán en las listas.

Si eres fanático de la GUI, puedes verificar Meld que @Alexander mencionó. Funciona bien tanto en Windows como en Linux.

Fábio
fuente
1

Para informar diferencias entre dirA y dirB, al tiempo que se actualiza / sincroniza.

rsync -auv <dirA> <dirB>

Kickaha
fuente