shell 递归地diff目录,忽略所有二进制文件

uelo1irk  于 2023-11-21  发布在  Shell
关注(0)|答案(6)|浏览(182)

在一个Fedora Constantine盒子上工作。我正在递归地查看diff两个目录以检查源代码的更改。由于项目的设置(在我自己参与该项目之前!* 叹息 ),目录中包含源代码和二进制文件,以及大型二进制数据集。虽然diffing最终在这些目录上工作,但如果我可以忽略二进制文件,可能需要20秒。
据我所知,diff没有“ignore binary file”模式,但有一个ignore参数,它会忽略文件中的正则表达式
*。我不知道该怎么写才能忽略二进制文件,不管扩展名是什么。
我正在使用下面的命令,但是它不能忽略二进制文件。有人知道如何修改这个命令来做到这一点吗?

diff -rq dir1 dir2

字符串

xlpyo6sf

xlpyo6sf1#

有点作弊,但我用的是:

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

字符串
这递归地比较dir1和dir2,sed删除二进制文件的行(以“Binary files“开头),然后重定向到输出文件。

oymdgrw7

oymdgrw72#

可以使用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

字符串

xcitsw88

xcitsw883#

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

7lrncoxx

7lrncoxx4#

如果项目中的二进制文件的名称遵循特定的模式(*.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

dojqjjoe

dojqjjoe5#

使用findfile命令的组合。这需要你在你的目录中对file命令的输出做一些研究;下面我假设你想diff的文件被报告为asdiff。或者,使用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

lh80um4z

lh80um4z6#

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

相关问题