82 votes

Diff un répertoire récursivement, en ignorant tous les fichiers binaires:

Travail sur une Fedora Constantine boîte. Je suis à la recherche d' diff deux répertoires de manière récursive pour vérifier la source de changements. En raison de la configuration du projet (avant mon propre engagement avec ledit projet! soupir), les répertoires contiennent à la fois source et les binaires, ainsi que de grands ensembles de données binaires. Tandis que la comparaison fonctionne éventuellement sur ces répertoires, il faudrait peut-être vingt secondes si je pouvais ignorer les fichiers binaires.

Comme je le comprends, diff ne dispose pas d'un 'ignorer fichier binaire" mode, mais ne disposent d'ignorer un argument qui ignore expression régulière dans un fichier. Je ne sais pas quoi écrire là pour ignorer les fichiers binaires, quelle que soit l'extension.

Je suis l'aide de la commande suivante, mais il n'ignore pas les fichiers binaires. Quelqu'un sait-il comment modifier cette commande pour faire cela?

diff -rq dir1 dir2

69voto

Shannon VanWagner Points 181

Un peu de triche mais voici ce que j'ai utilisé:

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

Cela compare récursivement dir1 à dir2, sed supprime les lignes des fichiers binaires (commençant par "fichiers binaires"), puis est redirigé vers le fichier de sortie.

33voto

jon Points 226

Peut-être utilisez-vous grep -I (ce qui équivaut à grep --binary-files=without-match ) comme filtre pour trier les fichiers binaires.

 dir1='folder-1'
dir2='folder-2'
IFS=$'\n'
for file in $(grep -Ilsr -m 1 '.' "$dir1"); do
   diff -q "$file" "${file/${dir1}/${dir2}}"
done
 

14voto

RecursivelyIronic Points 1205

Je suis venu à cette (vieille) question la recherche de quelque chose de similaire (fichiers de configuration sur un héritage serveur de production par rapport à défaut, l'installation d'apache). Suivant @fearlesstost de la suggestion dans les commentaires, git est suffisamment léger et rapide qu'il est probablement plus simple que l'une des suggestions ci-dessus. Copie version1 vers un nouveau répertoire. Ensuite il faut faire:

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

Maintenant supprimer tous les fichiers de la version 1 de ce répertoire et copier la version 2 dans le répertoire. Faire maintenant:

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

Cela va vous montrer Git version de toutes les différences entre le premier commit et la seconde. Pour les fichiers binaires, il va juste dire qu'ils diffèrent. Alternativement, vous pouvez créer une branche pour chaque version et essayer de les fusionner à l'aide de git de la fusion des outils.

0voto

Troy Points 588

En guise de vérification sommaire, vous pouvez ignorer les fichiers qui correspondent à / \ 0 /.

0voto

Fredrik Pihl Points 20944

Utilisez une combinaison de find et de la file commande. Cela vous oblige à faire quelques recherches sur la production de l' file commande dans votre répertoire; ci-dessous, je suis en supposant que les fichiers que vous souhaitez diff est signalé comme ascii. OU, utilisez grep -v de filtrer les fichiers binaires.

#!/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

Puisque vous le savez probablement les noms de l'énorme binaires, les placer dans une table de hachage de tableau et ne faire que la diff quand un fichier n'est pas dans la table de hachage,quelque chose comme ceci:

#!/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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X