Diff Un Directorio Recursivamente, Ignorando Todos Los Archivos Binarios:


Trabajando en una caja de Fedora Constantine. Estoy buscando diff dos directorios recursivamente para comprobar si hay cambios en el código fuente. Debido a la configuración del proyecto (antes de mi propio compromiso con dicho proyecto! sigh), los directorios contienen tanto fuentes como binarios, así como grandes conjuntos de datos binarios. Mientras diffing finalmente funciona en estos directorios, tomaría quizás veinte segundos si pudiera ignorar los archivos binarios.

Por lo que entiendo, diff no tiene un ' ignorar binary file ' mode, pero tiene un argumento ignore que ignorará la expresión regular dentro de un archivo. No se qué escribir allí para ignorar los archivos binarios, independientemente de la extensión.

Estoy usando el siguiente comando, pero no ignora los archivos binarios. ¿Alguien sabe cómo modificar este comando para hacer esto?

Dif-rq dir1 dir2

Author: Zéychin, 2011-07-15

6 answers

Tal vez use grep -I (que es equivalente a grep --binary-files=without-match) como un filtro para ordenar archivos binarios.

dir1='folder-1'
dir2='folder-2'
IFS=$'\n'
for file in $(grep -Ilsr -m 1 '.' "$dir1"); do
   diff -q "$file" "${file/${dir1}/${dir2}}"
done
 30
Author: jon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-15 19:04:55

Tipo de trampa, pero esto es lo que usé:

diff -r dir1/ dir2/ | sed '/Binary\ files\ /d' >outputfile

Esto compara recursivamente dir1 con dir2, sed elimina las líneas para los archivos binarios(comienza con "Archivos binarios "), luego se redirige al archivo de salida.

 60
Author: Shannon VanWagner,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-03-17 19:31:43

Llegué a esta (antigua) pregunta buscando algo similar (archivos de configuración en un servidor de producción heredado en comparación con la instalación predeterminada de apache). Siguiendo la sugerencia de @fearlesstost en los comentarios, git es lo suficientemente ligero y rápido que probablemente sea más sencillo que cualquiera de las sugerencias anteriores. Copie la versión 1 a un nuevo directorio. Entonces haz:

git init
git add .
git commit -m 'Version 1'

Ahora elimine todos los archivos de la versión 1 en este directorio y copie la versión 2 en el directorio. Ahora:

git add .
git commit -m 'Version 2'
git show

Esto te mostrará la versión de Git de todas las diferencias entre la primera confirmación y la segunda. Para los archivos binarios solo dirá que difieren. Alternativamente, puedes crear una rama para cada versión e intentar fusionarlas usando las herramientas de fusión de git.

 11
Author: RecursivelyIronic,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-02-15 22:16:55

Si los nombres de los archivos binarios en su proyecto siguen un patrón específico (*.o,*. so,...), como suelen hacer, puede poner esos patrones en un archivo y especificarlo usando -X (guion X).

Contenido de mi archivo " exclude" *.o *.tan *.git

diff -X exclude_file -r . other_tree > my_diff_file
 1
Author: Mohan S Nayaka,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-02 08:52:28

Use una combinación de find y el comando file. Esto requiere que investigue la salida del comando file en su directorio; a continuación asumo que los archivos que desea comparar se reportan como ascii. O bien, use grep -v para filtrar los archivos binarios.

#!/bin/bash

dir1=/path/to/first/folder
dir2=/path/to/second/folder

cd $dir1
files=$(find . -type f -print | xargs file | grep ASCII | cut -d: -f1)

for i in $files;
do
    echo diffing $i ---- $dir2/$i
    diff -q $i $dir2/$i
done

Ya que probablemente conozcas los nombres de los binarios enormes, colócalos en un hash-array y solo haz la diferencia cuando un archivo no está en el hash, algo como esto:

#!/bin/bash

dir1=/path/to/first/directory
dir2=/path/to/second/directory

content_dir1=$(mktemp)
content_dir2=$(mktemp)

$(cd $dir1 && find . -type f -print > $content_dir1)
$(cd $dir2 && find . -type f -print > $content_dir2)

echo Files that only exist in one of the paths
echo -----------------------------------------
diff $content_dir1 $content_dir2    

#Files 2 Ignore
declare -A F2I
F2I=( [sqlite3]=1 [binfile2]=1 )

while read f;
do
    b=$(basename $f)
    if ! [[ ${F2I[$b]} ]]; then
        diff $dir1/$f $dir2/$f
    fi
done < $content_dir1
 0
Author: Fredrik Pihl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-07-15 21:24:07

Bueno, como una especie de comprobación cruda, podría ignorar los archivos que coinciden con /\0/.

 0
Author: Troy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-29 07:17:40