递归地区分目录,忽略所有二进制文件


76

在Fedora Constantine盒子上工作。我正在diff递归地查找两个目录以检查源更改。由于项目的设置(在我自己参与上述项目之前!sigh),目录包含源代码和二进制文件以及大型二进制数据集。虽然差异最终适用于这些目录,但如果我可以忽略二进制文件,则可能需要二十秒钟。

据我了解,DIFF没有一个“忽略二进制文件”模式,但确实有一个忽略的参数,它会忽略正则表达式的文件。无论扩展名如何,我都不知道该写些什么来忽略二进制文件。

我正在使用以下命令,但它不会忽略二进制文件。有谁知道如何修改此命令来做到这一点?

diff -rq dir1 dir2

2
尝试使用cmp代替diff,不会忽略二进制文件,但是应该更快
Fredrik Pihl

2
伊克。这是源代码控制的后代理由。如果您不使用它,应该使用。如果您没有做出决定,则应该热情地争论。您的问题将随着正确的git设置而消失...
fearlesstost

6
哦,相信我。我知道。我正在进行本科生研究,这与应有的设置还不完全相同。相信我。我知道。CVS / SVN / GIT将解决此问题。知道什么比那更糟吗?我被分配从事很少甚至没有文档的Fortran项目。这个目录中有8个版本的项目,每个版本都有不同的makefile(几乎;)),它们执行相同的操作。相信我,我正在尽力与我的监督员争论。
Zéychin

Answers:


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

这看起来非常有希望。我会检查一下,让您知道如何进行/如果可以解决,请接受!
Zéychin

2
有人知道目的IFS=$'\n'吗?
Zubin 2014年

5
它是bash内部变量。在tldp.org/LDP/abs/html/internalvariables.html下查找IFS,了解其精确定义和行为。
严苛的

1
@Zubin IFS表示内部字段分隔符,用于通过按IFS给定的值拆分字符串来创建数组
Be Wake Pandey


65

有点作弊,但这是我用的:

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

递归比较dir1和dir2,sed删除二进制文件的行(以“ Binary files”开头),然后将其重定向到outputfile。


7
@Serg您可以使用该-x标志排除文件。diff -r -x '*.xml' dir1 dir2另请尝试,man diff以获取更多信息。
xdhmoore

1
如果您使用的是其他语言的系统,请用Binary\ files\ 您的语言中的相应单词替换。它应该是第一个或两个词。用德语显示Binärdateien\
kap

1
@xdhmoore感谢您的评论!要添加到它,-x也是可重复的,因为如果要排除多个模式。有点像-x '*.ext1' -x '*.ext2' -x 'ext3'
Vasan

13

我遇到了这个(旧的)问题,正在寻找类似的东西(与默认的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的合并工具合并它们。


5

如果项目中二进制文件的名称像通常一样遵循特定的模式(*.o,,*.so...),则可以将这些模式放入文件中并使用-X(连字符X)指定。

我的内容 exclude_file

*.o
*.so
*.git

命令:

diff -X exclude_file -r . other_tree > my_diff_file

更新:

-x可以代替来用于-X在命令行而不是文件中指定排除模式:

diff -r -x *.o -x *.so -x *.git dir1 dir2

1
它是-x NOT -X。
code_dweller

2
@code_dweller两者都存在:-x用于排除命令行上的模式,而-X表示包含所有要排除的模式的文件。
simlev

0

使用findfile命令的组合。这要求您对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

好吧,作为一种粗略的检查,您可以忽略匹配/ \ 0 /的文件。


1
问题是,它看起来完全不像diff一样支持忽略文件。
Zéychin

2
-x标志可用于忽略文件。
xdhmoore 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.