Diferentes archivos presentes en dos directorios diferentes


303

Tengo dos directorios con la misma lista de archivos. Necesito comparar todos los archivos presentes en ambos directorios usando el diffcomando. ¿Hay una opción de línea de comando simple para hacerlo, o tengo que escribir un script de shell para obtener la lista de archivos y luego recorrerlos?

Respuestas:


422

Puede usar el diffcomando para eso:

diff -bur folder1/ folder2/

Esto generará una diferencia recursiva que ignora los espacios, con un contexto unificado:

  • b bandera significa ignorar espacios en blanco
  • La bandera u significa un contexto unificado (3 líneas antes y después)
  • r flag significa recursivo

99
Puede tener acceso al diffcomando descargando las utilidades GNU para Win32 .
Laurent Etiemble

77
También he encontrado que - la opción breve es útil; obtienes una lista de archivos modificados y puedes procesarlos por separado
Dariusz

27
Para otros que se preguntan, -bignora los cambios en los espacios en blanco y -uda 3 líneas de búfer.
Rattray

28
Es más fácil recordar este comando si usas rub en lugar de bur, es decirdiff -rub folder1/ folder2/
SomeGuyOnAComputer

11
Me imagino -burque sería fácil de recordar si vivieras en un clima frío.
AlanH

126

Si solo le interesa ver los archivos que difieren, puede usar:

diff -qr dir_one dir_two | sort

La opción "q" solo mostrará los archivos que difieren pero no el contenido que difiere, y "ordenar" organizará la salida alfabéticamente.


1
¡Eso es genial! También funciona de manera eficiente, es decir, si existe un subdirectorio completo solo en uno de los directorios, deja de repetirse e informa solo el subdirectorio en sí (sin su contenido sucesor). ¡¡muy agradable!!
SomethingSomething

Este es un muy buen primer paso: ver lo que, en todo caso, no se diferencian, y luego hacer una descripción detallada diffde cada par de archivos diferentes. El enfoque de uno sería muy diferente si solo uno o dos archivos difieren en comparación con si docenas de archivos difieren. ¡Podría perderme en la salida de diffing decenas de archivos a la vez!
jvriesem

Además, puede incluir un -x PATTERNcomando para excluir ciertos subdirectorios. Por ejemplo, diff -qr repo1 repo2 -x ".git"comparará dos directorios (repo1 y repo2) pero excluirá los archivos en la carpeta .git de los directorios respectivos.
ViFI

20

Diff tiene una opción -rque está destinada a hacer precisamente eso.

diff -r dir1 dir2


11

diffno solo puede comparar dos archivos, sino que, mediante la -ropción, puede recorrer árboles de directorios completos, verificando recursivamente las diferencias entre subdirectorios y archivos que ocurren en puntos comparables en cada árbol.

$ man diff

...

-r  --recursive
        Recursively compare any subdirectories found.

...

3

Si es GNU diff, debería poder apuntarlo a los dos directorios y usar la opción -r.

De lo contrario, intente usar

for i in $(\ls -d ./dir1/*); do diff ${i} dir2; done

Nota: como señaló Dennis en la sección de comentarios, en realidad no es necesario hacer la sustitución de comandos en el ls. He estado haciendo esto durante tanto tiempo que estoy haciendo esto prácticamente en piloto automático y sustituyendo el comando que necesito para obtener mi lista de archivos para comparar.

También olvidé agregar que hago '\ ls' para deshabilitar temporalmente mi alias de ls a GNU ls para que pierda la información de formato de color de la lista devuelta por GNU ls.


2
No es necesario usar ls:for i in ./dir1/*
pausa hasta nuevo aviso.

1
@ Dennis, atajo funky. +1. Estoy tan acostumbrado a hacer la sustitución de comandos, aunque es automático y solo uso el comando que necesito, por ejemplo, a veces uso find. Usar ls también me permite jugar con la lista de directorios más, por ejemplo, en función del tiempo inverso en lugar de la secuencia predeterminada.
Rob Wells el

0

Aquí hay un script para mostrar las diferencias entre los archivos en dos carpetas. Funciona de forma recursiva. Cambiar dir1 y dir2.

(search() { for i in $1/*; do [ -f "$i" ] && (diff "$1/${i##*/}" "$2/${i##*/}" || echo "files: $1/${i##*/}   $2/${i##*/}"); [ -d "$i" ] && search "$1/${i##*/}" "$2/${i##*/}"; done }; search "dir1" "dir2" )

0

Si no desea comparar específicamente el contenido de los archivos y solo verifica cuál no está presente en ambos directorios, puede comparar listas de archivos, generadas por otro comando.

diff <(find DIR1 -printf '%P\n' | sort) <(find DIR2 -printf '%P\n' | sort) | grep '^[<>]'

-printf '%P\n'le indica findque no prefija las rutas de salida con el directorio raíz.

También he agregado sortpara asegurarme de que el orden de los archivos será el mismo en ambas llamadas find.

Al grepfinal, se elimina la información sobre líneas de entrada idénticas.


-4

Prueba esto:

diff -rq /path/to/folder1 /path/to/folder2      

2
Esto duplica una respuesta existente y no agrega contenido nuevo. No publique una respuesta a menos que realmente tenga algo nuevo que aportar.
Toby Speight
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.