使用Fedora Constantine框。我正在寻找diff
递归的两个目录来检查源更改。由于项目的设置(在我自己参与所述项目之前!叹息),目录包含源和二进制文件,以及大型二进制数据集。虽然diffing最终可以在这些目录上运行,但如果我可以忽略二进制文件,则可能需要20秒。
据我所知,diff没有'忽略二进制文件'模式,但确实有一个忽略参数,它会忽略文件中正则表达式 。我不知道在那里写什么来忽略二进制文件,无论扩展名如何。
我正在使用以下命令,但它不会忽略二进制文件。有谁知道如何修改此命令来执行此操作?
diff -rq dir1 dir2
答案 0 :(得分:64)
有点作弊,但这是我用的:
diff -r dir1/ dir2/ | sed '/Binary\ files\ /d' >outputfile
这递归地将dir1与dir2进行比较,sed删除二进制文件的行(以“二进制文件”开头),然后将其重定向到输出文件。
答案 1 :(得分:32)
也许使用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 :(得分:11)
我来到这个(旧)问题寻找类似的东西(遗留生产服务器上的配置文件与默认的apache安装相比)。根据@ fearlesstost在评论中的建议,git
足够轻巧,快速,可能比上述任何建议更直接。 将版本1复制到新目录。然后做:
git init
git add .
git commit -m 'Version 1'
现在删除此目录中版本1的所有文件,并将版本2复制到目录中。现在做:
git add .
git commit -m 'Version 2'
git show
这将向您展示第一次提交和第二次提交之间所有差异的Git版本。对于二进制文件,它只会说它们不同。或者,您可以为每个版本创建一个分支,并尝试使用git的合并工具合并它们。
答案 3 :(得分:1)
如果项目中二进制文件的名称遵循特定模式(* .o,* .so,...),就像通常那样,您可以将这些模式放在文件中并使用-X指定它(连字符X)。
我的“排除档案”的内容 *的.o *。所以 * git的
diff -X exclude_file -r . other_tree > my_diff_file
答案 4 :(得分:0)
好吧,作为粗略的检查,您可以忽略与/ \ 0 /.
匹配的文件答案 5 :(得分:0)
使用find
和file
命令的组合。这需要您对目录中file
命令的输出进行一些研究;下面我假设您要diff的文件报告为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