web-dev-qa-db-fra.com

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

Travailler sur une boîte Fedora Constantine. Je cherche à diff deux répertoires de manière récursive pour vérifier les modifications apportées à la source. En raison de la configuration du projet (avant mon propre engagement avec ledit projet! soupir ), les répertoires contiennent à la fois le code source et les fichiers binaires, ainsi jeux de données binaires. Bien que diff puisse éventuellement fonctionner sur ces répertoires, cela prendrait peut-être 20 secondes si je pouvais ignorer les fichiers binaires.

Autant que je sache, diff n'a pas de mode 'ignorer le fichier binaire', mais a un argument ignore qui ignorera l'expression régulière dedans un fichier. Je ne sais pas quoi écrire pour ignorer les fichiers binaires, quelle que soit leur extension.

J'utilise la commande suivante, mais elle n'ignore pas les fichiers binaires. Est-ce que quelqu'un sait comment modifier cette commande pour faire cela?

diff -rq dir1 dir2
71
Zéychin

Peut-être utiliser 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
32
jon

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.

64
Shannon VanWagner

Je suis arrivé à cette (ancienne) question à la recherche de quelque chose de similaire (fichiers de configuration sur un serveur de production hérité comparé à l'installation par défaut d'Apache). Suivant les suggestions de @ fearlesstost dans les commentaires, git est suffisamment léger et rapide pour être probablement plus simple que les suggestions ci-dessus. Copier version1 dans un nouveau répertoire. Alors fais:

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

Supprimez maintenant tous les fichiers de la version 1 de ce répertoire et copiez la version 2 dans ce répertoire. Maintenant faire:

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

Cela vous montrera la version de Git de toutes les différences entre le premier commit et le second. Pour les fichiers binaires, il sera simplement dit qu'ils diffèrent. Vous pouvez également créer une branche pour chaque version et essayer de les fusionner à l'aide des outils de fusion de git.

11
RecursivelyIronic

Si les noms des fichiers binaires de votre projet suivent un modèle spécifique (* .o, * .so, ...), comme ils le font habituellement, vous pouvez placer ces modèles dans un fichier et le spécifier à l'aide de -X (trait d'union X). ).

contenu de mon "fichier d'exclusion" * .o * .so * .git

diff -X exclude_file -r . other_tree > my_diff_file
1
Mohan S Nayaka

Utilisez une combinaison de find et de la commande file. Cela nécessite que vous fassiez des recherches sur le résultat de la commande file dans votre répertoire; ci-dessous, je suppose que les fichiers que vous souhaitez différencier sont signalés sous le nom ascii. Ou utiliser grep -v pour 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 connaissez probablement les noms des fichiers binaires énormes, placez-les dans un tableau de hachage et ne faites le diff que lorsqu'un fichier ne se trouve pas dans le hachage, à peu près 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
0
Fredrik Pihl

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

0
Troy