solo recursivo entre ejemplos diferencias comando archivos linux bash shell command-line diff

recursivo - diff entre dos archivos linux



Diferencia entre dos directorios en Linux (15)

El complemento DirDiff de vim es otra herramienta muy útil para comparar directorios.

vim -c "DirDiff dir1 dir2"

No solo enumera qué archivos son diferentes entre los directorios, sino que también le permite inspeccionar / modificar con vimdiff los archivos que son diferentes.

Estoy tratando de encontrar los archivos existentes en un directorio pero no en el otro, intenté usar este comando:

diff -q dir1 dir2

El problema con el comando anterior es que encuentra los archivos en dir1 pero no en dir2 , así como los archivos en dir2 pero no en dir1 ,

Estoy intentando encontrar los archivos en dir1 pero no solo en dir2 .

Aquí hay una pequeña muestra de cómo se ven mis datos.

dir1 dir2 dir3 1.txt 1.txt 1.txt 2.txt 3.txt 3.txt 5.txt 4.txt 5.txt 6.txt 7.txt 8.txt

Otra pregunta en mi mente es ¿cómo puedo encontrar los archivos en dir1 pero no en dir2 o dir3 en un solo comando?


Esta respuesta optimiza una de las sugerencias de @ Adail-Junior al agregar la opción -D , que es útil cuando ninguno de los directorios que se comparan son repositorios git:

git diff -D --no-index dir1/ dir2/

Si usa -D , no verá comparaciones con /dev/null : text Binary files a/whatever and /dev/null differ


Este es el script de bash para imprimir comandos para sincronizar dos directorios

dir1=/tmp/path_to_dir1 dir2=/tmp/path_to_dir2 diff -rq $dir1 $dir2 | sed -e "s|Only in $dir2/(.*/): /(.*/)|cp -r $dir2/1//2 $dir1/1|" | sed -e "s|Only in $dir1/(.*/): /(.*/)|cp -r $dir1/1//2 $dir2/1|"


Esto debería hacer el trabajo:

diff -rq dir1 dir2

Opciones explicadas (a través de la página man de diff (1)):

  • -r - Compara recursivamente cualquier subdirectorio encontrado.
  • -q - Salida solo si los archivos difieren.

Esto es un poco tarde pero puede ayudar a alguien. No estoy seguro si diff o rsync escupen solo nombres de archivos en un formato simple como este. Gracias a plhn por dar esa buena solución que amplié a continuación.

Si solo desea los nombres de archivo, así que es fácil copiar los archivos que necesita en un formato limpio, puede usar el comando buscar.

comm -23 <(find dir1 | sed ''s/dir1////''| sort) <(find dir2 | sed ''s/dir2////''| sort) | sed ''s/^///dir1/''

Esto supone que tanto dir1 como dir2 están en la misma carpeta principal. simplemente elimina la carpeta principal para que puedas comparar manzanas con manzanas. El último sed solo vuelve a poner el nombre dir1.

Si solo quieres archivos:

comm -23 <(find dir1 -type f | sed ''s/dir1////''| sort) <(find dir2 -type f | sed ''s/dir2////''| sort) | sed ''s/^///dir1/''

Del mismo modo para los directorios:

comm -23 <(find dir1 -type d | sed ''s/dir1////''| sort) <(find dir2 -type d | sed ''s/dir2////''| sort) | sed ''s/^///dir1/''


GNU grep puede invertir la búsqueda con la opción -v . Esto hace que grep reporte las líneas, que no coinciden. De este modo, puede eliminar los archivos en dir2 de la lista de archivos en dir1 .

grep -v -F -x -f <(find dir2 -type f -printf ''%P/n'') <(find dir1 -type f -printf ''%P/n'')

Las opciones -F -x dicen a grep que realice una búsqueda de cadena en toda la línea.


Insatisfecho con todas las respuestas, ya que la mayoría de ellas funcionan muy lentamente y producen resultados innecesariamente largos para directorios grandes, escribí mi propio script de Python para comparar dos carpetas.

A diferencia de muchas otras soluciones, no compara el contenido de los archivos. Tampoco entra dentro de los subdirectorios que faltan en otro directorio. Así que la salida es bastante concisa y el script funciona rápido.

#!/usr/bin/env python3 import os, sys def compare_dirs(d1: "old directory name", d2: "new directory name"): def print_local(a, msg): print(''DIR '' if a[2] else ''FILE'', a[1], msg) # ensure validity for d in [d1,d2]: if not os.path.isdir(d): raise ValueError("not a directory: " + d) # get relative path l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)] l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)] # determine type: directory or file? l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1]) l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2]) i1 = i2 = 0 common_dirs = [] while i1<len(l1) and i2<len(l2): if l1[i1][0] == l2[i2][0]: # same name if l1[i1][2] == l2[i2][2]: # same type if l1[i1][2]: # remember this folder for recursion common_dirs.append((l1[i1][1], l2[i2][1])) else: print_local(l1[i1],''type changed'') i1 += 1 i2 += 1 elif l1[i1][0]<l2[i2][0]: print_local(l1[i1],''removed'') i1 += 1 elif l1[i1][0]>l2[i2][0]: print_local(l2[i2],''added'') i2 += 1 while i1<len(l1): print_local(l1[i1],''removed'') i1 += 1 while i2<len(l2): print_local(l2[i2],''added'') i2 += 1 # compare subfolders recursively for sd1,sd2 in common_dirs: compare_dirs(sd1, sd2) if __name__=="__main__": compare_dirs(sys.argv[1], sys.argv[2])

Uso de la muestra:

user@laptop:~$ python3 compare_dirs.py dir1/ dir2/ DIR dir1/out/flavor-domino removed DIR dir2/out/flavor-maxim2 added DIR dir1/target/vendor/flavor-domino removed DIR dir2/target/vendor/flavor-maxim2 added FILE dir1/tmp/.kconfig-flavor_domino removed FILE dir2/tmp/.kconfig-flavor_maxim2 added DIR dir2/tools/tools/LiveSuit_For_Linux64 added

O si solo quieres ver los archivos del primer directorio:

user@laptop:~$ python3 compare_dirs.py dir2/ dir1/ | grep dir1 DIR dir1/out/flavor-domino added DIR dir1/target/vendor/flavor-domino added FILE dir1/tmp/.kconfig-flavor_domino added

PS Si necesita comparar tamaños de archivos y hashes para posibles cambios, publiqué un script actualizado aquí: https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779


La respuesta aceptada también mostrará una lista de los archivos que existen en ambos directorios, pero que tienen un contenido diferente. Para listar SOLAMENTE los archivos que existen en dir1 puede usar:

diff -r dir1 dir2 | grep ''Only in'' | grep dir1 | awk ''{print $4}'' > difference1.txt

Explicación:

  • diff -r dir1 dir2: compare
  • grep ''Only in'': obtiene líneas que contienen ''Only in''
  • grep dir1: obtener líneas que contienen dir


Otro enfoque (quizás más rápido para directorios grandes):

$ find dir1 | sed ''s,^[^/]*/,,'' | sort > dir1.txt && find dir2 | sed ''s,^[^/]*/,,'' | sort > dir2.txt $ diff dir1.txt dir2.txt

El comando sed elimina el primer componente del directorio gracias a la publicación de Erik )


Una buena manera de hacer esta comparación es usar find con md5sum , y luego un diff .

Ejemplo:

Utilice find para enumerar todos los archivos en el directorio, luego calcule el hash md5 para cada archivo y canalícelo a un archivo:

find /dir1/ -type f -exec md5sum {} /; > dir1.txt

Realice el mismo procedimiento en el otro directorio:

find /dir2/ -type f -exec md5sum {} /; > dir2.txt

Luego compara el resultado dos archivos con "diff":

diff dir1.txt dir2.txt

Esta estrategia es muy útil cuando los dos directorios que se comparan no están en la misma máquina y debe asegurarse de que los archivos sean iguales en ambos directorios.

Otra buena manera de hacer el trabajo es usando git.

git diff --no-index dir1/ dir2/

¡Atentamente!


Una forma simplificada de comparar 2 directorios usando el comando DIFF

diff filename.1 filename.2> filename.dat >> Entrar

abrir filename.dat una vez finalizada la ejecución

y verá: Solo en nombre_archivo.1: nombre_archivo.2 Solo en: nombre_directorio: nombre_de_archivo1 Solo en: nombre_directorio: nombre_de_archivo2


kdiff3 tiene una interfaz agradable para archivos y directorios.

Compruebe la URL: http://kdiff3.sourceforge.net

Funciona bajo Windows y Linux.


comm -23 <(ls dir1 |sort) <(ls dir2|sort)

Este comando le dará archivos que están en dir1 y no en dir2.

Acerca del signo <( ) , puede buscarlo en Google como ''sustitución de proceso''.


diff -r dir1 dir2 | grep dir1 | awk ''{print $4}'' > difference1.txt

Explicación:

  • diff -r dir1 dir2 muestra qué archivos están solo en dir1 y aquellos solo en dir2 y también los cambios de los archivos presentes en ambos directorios, si los hay.

  • diff -r dir1 dir2 | grep dir1 diff -r dir1 dir2 | grep dir1 muestra qué archivos están solo en dir1

  • awk para imprimir solo nombre de archivo.