рекурсивно проверять каталог, игнорируя все двоичные файлы - PullRequest
71 голосов
/ 15 июля 2011

Работа над коробкой Fedora Constantine. Я ищу diff две директории рекурсивно, чтобы проверить изменения источника. Из-за настройки проекта (до моего участия в этом проекте! sigh ) каталоги содержат как исходные тексты, так и двоичные файлы, а также большие наборы двоичных данных. В то время как diffing в конечном итоге работает с этими каталогами, возможно, потребуется двадцать секунд, если я смогу игнорировать двоичные файлы.

Насколько я понимаю, diff не имеет режима игнорирования двоичного файла, но имеет аргумент игнорирования, который будет игнорировать регулярное выражение в файле. Я не знаю, что там писать, чтобы игнорировать двоичные файлы независимо от расширения.

Я использую следующую команду, но она не игнорирует двоичные файлы. Кто-нибудь знает, как изменить эту команду, чтобы сделать это?

diff -rq dir1 dir2

Ответы [ 6 ]

64 голосов
/ 17 марта 2012

Вид мошенничества, но вот что я использовал:

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

Это рекурсивно сравнивает dir1 с dir2, sed удаляет строки для двоичных файлов (начинается с "Binary files"), затем перенаправляется в выходной файл.

32 голосов
/ 15 июля 2011

Возможно использовать grep -I (что эквивалентно grep --binary-files=without-match) в качестве фильтра для сортировки двоичных файлов.

dir1='folder-1'
dir2='folder-2'
IFS=$'\n'
for file in $(grep -Ilsr -m 1 '.' "$dir1"); do
   diff -q "$file" "${file/${dir1}/${dir2}}"
done
11 голосов
/ 16 февраля 2013

Я пришел к этому (старому) вопросу в поисках чего-то похожего (файлы конфигурации на устаревшем производственном сервере по сравнению с установкой Apache по умолчанию)Следуя предложению @earlesstost в комментариях, git является достаточно легким и быстрым, что, вероятно, более простым, чем любое из приведенных выше. Скопируйте version1 в новый каталог.Затем выполните:

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

Теперь удалите все файлы из версии 1 в этом каталоге и скопируйте версию 2 в каталог.Теперь сделайте:

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

Это покажет вам версию Git всех различий между первым коммитом и вторым.Для двоичных файлов будет просто сказать, что они отличаются.Кроме того, вы можете создать ветку для каждой версии и попытаться объединить их, используя инструменты слияния git.

1 голос
/ 02 января 2017

Если имена бинарных файлов в вашем проекте следуют определенному шаблону (* .o, * .so, ...), как обычно, вы можете поместить эти шаблоны в файл и указать его, используя -X (дефис X).

содержимое моего "файла исключений" * .o *.так * .Git

diff -X exclude_file -r . other_tree > my_diff_file
0 голосов
/ 15 июля 2011

Используйте комбинацию find и команду file. Это требует, чтобы вы проверили вывод команды file в вашем каталоге; ниже я предполагаю, что файлы, которые вы хотите проверить, указаны как ascii. ИЛИ, используйте grep -v для фильтрации двоичных файлов.

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

Поскольку вы, вероятно, знаете имена огромных двоичных файлов, поместите их в хеш-массив и выполняйте сравнение только тогда, когда файл не находится в хеш-коде, что-то вроде этого:

#!/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 голосов
/ 15 июля 2011

Ну, в качестве грубой проверки вы можете игнорировать файлы, которые соответствуют /\0/.

...