Рекурсивно проверять каталог, игнорируя все двоичные файлы
Работа над коробкой Fedora Constantine. Я ищу diff
две директории рекурсивно, чтобы проверить изменения источника. Из-за настройки проекта (до моего участия в проекте! Sigh) каталоги содержат как исходные тексты, так и двоичные файлы, а также большие наборы двоичных данных. В то время как diffing в конечном итоге работает с этими каталогами, мне потребовалось бы около двадцати секунд, если бы я мог игнорировать двоичные файлы.
Насколько я понимаю, diff не имеет режима "игнорировать двоичный файл", но имеет аргумент игнорирования, который будет игнорировать регулярное выражение внутри файла. Я не знаю, что там писать, чтобы игнорировать двоичные файлы, независимо от расширения.
Я использую следующую команду, но она не игнорирует двоичные файлы. Кто-нибудь знает, как изменить эту команду, чтобы сделать это?
diff -rq dir1 dir2
Ответы
Ответ 1
Возможно, используйте 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
Ответ 2
Вид обмана, но вот что я использовал:
diff -r dir1/ dir2/ | sed '/Binary\ files\ /d' >outputfile
Это рекурсивно сравнивает dir1 с dir2, sed удаляет строки для двоичных файлов (начинается с "Двоичные файлы" ), затем перенаправляется в выходной файл.
Ответ 3
Я пришел к этому (старому) вопросу в поисках чего-то подобного (файлы Config на устаревшем производственном сервере по сравнению с установкой apache по умолчанию). Следуя предложению @fearlesstost в комментариях, git
достаточно легкий и быстрый, что, вероятно, более прямолинейно, чем любое из приведенных выше предложений. Скопировать version1 в новый каталог. Затем выполните:
git init
git add .
git commit -m 'Version 1'
Теперь удалите все файлы из версии 1 в этом каталоге и скопируйте версию 2 в каталог. Теперь выполните:
git add .
git commit -m 'Version 2'
git show
Это покажет вам версию Git всех различий между первым фиксатором и вторым. Для двоичных файлов он просто скажет, что они отличаются. Кроме того, вы можете создать ветвь для каждой версии и попытаться объединить их с помощью инструментов Git merge.
Ответ 4
Если имена бинарных файлов в вашем проекте следуют определенному шаблону (*.o
, *.so
,...), как они обычно делают, вы можете поместить эти шаблоны в файл и указать его с помощью -X
(дефис X).
Содержимое моего exclude_file
*.o
*.so
*.git
Команда:
diff -X exclude_file -r . other_tree > my_diff_file
UPDATE:
-x
можно использовать вместо -X
, чтобы указать шаблоны исключения в командной строке, а не в файле:
diff -r -x *.o -x *.so -x *.git dir1 dir2
Ответ 5
Ну, как грубая сортировка, вы можете игнорировать файлы, которые соответствуют /\ 0/.
Ответ 6
Используйте комбинацию 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
Поскольку вы, вероятно, знаете имена огромных двоичных файлов, поместите их в хэш-массив и выполняйте только diff, когда файл не находится в хэше, что-то вроде этого:
#!/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