给定两个目录树,如何找出内容不同的文件?


786

如果要查找两个目录树之间的差异,通常只执行:

diff -r dir1/ dir2/

这将准确输出相应文件之间的区别。我只想获取内容不同的相应文件的列表。我以为这只是将命令行选项传递给的问题diff,但是我在手册页上找不到任何内容。

有什么建议么?



1
关于其中一个目录,如何仅获取另一个目录中多余的文件/目录?
Sandeepan Nath

使用dircmp在UNIX(未Linux)的命令
roblogic

Answers:


1118

您说过Linux,所以您很幸运(至少它应该可用,不确定何时添加):

diff --brief --recursive dir1/ dir2/ # GNU long options
diff -qr dir1/ dir2/ # common short options

应该做你所需要的。

如果您还想查看两个目录中可能不存在的文件的差异,请执行以下操作:

diff --brief --recursive --new-file dir1/ dir2/ # GNU long options
diff -qrN dir1/ dir2/ # common short options

12
真好 但更短的是diff -qr dir1/ dir2/,我的扩展版本为diff -qr dir1/ dir2/ | grep ' differ'
sobi3ch 2015年

1
@skv为什么?这与答案相同。我只更改--brief了它的快捷方式-q
sobi3ch 2015年

2
@skv并非最初提出的问题,而是更新了答案以适应该问题。
Mark Loeser

3
@MikeMaxwell它必须是--brief-brief被解释为-b -r -i -e -f,换言之,被解释为一组标志,而不是单个选项。
daboross

2
@daboross:哇,我一直在使用Unix / Linux,但我从未意识到'-'和'-'之间没有区别。(我认为开始时不存在'-'。)谢谢您的解释!
Mike Maxwell '18

287

我使用的命令是:

diff -qr dir1/ dir2/

它与Mark的完全相同:)但是他的回答使我感到困扰,因为它使用了不同类型的标志,并且使我看上去两次。使用Mark更详细的标志,它将是:

diff  --brief --recursive dir1/ dir2/

当其他答案完全可以接受时,我深表歉意。不能阻止自己...努力减少学究。


3
完全欣赏一致性-但不会感到难过;我也赞成Mark的回答;)
Gerard

10
..so用不同的味道放不同的答案有意义吗?恕我直言,不!将两个答案组合成一个一致的答案是否有意义?是!;)
sobi3ch 2015年

1
就一个问题; 代表什么q?它是某物的缩写吗?我找不到任何逻辑q..
kramer65 '16

3
@ kramer65-它与“ --brief”相同,但是我想您想知道为什么q吗?也许很快?根据手册页,“-b”表示“忽略空白量的变化”。
FPC

3
我相信@ kramer65 q是for的quiet,通常意思是比较冗长。
Gogeta70 '17

105

我喜欢用 git diff --no-index dir1/ dir2/,因为它可以显示颜色差异(如果您在git config中设置了该选项),并且因为它在长页输出中使用“少”显示了所有差异。


25
整齐。谁能想到git可以区分任意目录,而不仅仅是针对其文件的repo?
Dan Dascalescu 2014年

2
Perl脚本colordiff在这里非常有用,可以与svn和normal diff一起使用。
费利佩·阿尔瓦雷斯

4
如果您比较(像我一样)2个Dirs作为单独的git项目/仓库,则需要--no-indexstackoverflow.com/a/1792477/473390上添加更多内容。我已经更新了@ alan-porter答案。
sobi3ch 2015年

我喜欢这一点,我还发现,如果将其添加--name-status 到命令行,它将仅显示带有“ M / A / D”标志的文件名列表,以表示“修改/添加/删除”状态。
gzh

碰巧这两个目录实际上都包含.git文件夹,如何从比较中排除它?
穆罕默德·察卡克

35

这两个命令基本上可以完成所需的任务:

diff --brief --recursive --no-dereference --new-file --no-ignore-file-name-case /dir1 /dir2 > dirdiff_1.txt

rsync --recursive --delete --links --checksum --verbose --dry-run /dir1/ /dir2/ > dirdiff_2.txt

它们之间的选择取决于dir1和dir2的位置:

当目录位于两个单独的驱动器上时,diff的性能优于rsync。但是,当比较的两个目录位于同一驱动器上时,rsync更快。这是因为diff并行将几乎相等的负载放在两个目录上,从而最大程度地增加了两个驱动器上的负载。

rsync在实际比较校验和之前先计算大块校验和。这样,将I / O操作按大块进行分组,并在单个驱动器上进行处理时可以提高处理效率。


3
rsync不仅对单个驱动器上的文件更快,而且允许比较子目录中的文件,例如,rsync --options /usr /bin /var /sbin /lib /old_root可以有效地比较当前根/(通过指定其中的所有子目录)和/old_root(例如,包含的某些旧备份/),这diff -r可以不行 并且,如果您假设具有相同大小,权限和时间戳的文件可能没有更改,那么省去--checksum将为您提供非常快的检查(如果不这样做的话)哪些文件可能已更改。
Matija Nalis

1
什么是目的--deletersync
汤姆·黑尔

2
--delete的目的是删除destination-dir中不再(不再)存在于source-dir中的现有文件
Thomas Munk

2
在这种情况下(带有--dry-run标志),什么都不会真正删除,rsync仅打印dir1中的文件,而不打印dir2中的文件
mata

11
我建议--dry-run始终放在第一位,以免意外遗忘它。
戴夫·拉格

22

Meld还是比较两个目录的好工具:

meld dir1/ dir2/

Meld有许多用于比较文件或目录的选项。如果两个文件不同,则很容易进入文件比较模式并查看确切的差异。


2
真好 我编写了一个简单的perl脚本来对树进行比较,但是遇到了限制。这似乎是票。
David Tonhofer

唯一的问题是,由于它是图形应用程序,因此不适合脚本编写。但是,如果您不介意GUI,那就太好了!谢谢。
DeanM '18年

我发现,meld如果在大型目录上使用它会变得非常缓慢。有什么可以更好地处理大型目录的吗?
弹出

@Popup,不是我所知道的。不过,您可以找到不同的文件名,例如:find dir1 dir2 | cut -d/ -f2- | sort | uniq --unique
Alexander

1
@Alexander-在那种情况下,我发现meld <(find dir1 -ls ) <(find dir2 -ls)使用bash进程替换效果很好。(zsh的=(command)工作效果更好。)
弹出

10

频道同胞“ billings”(具有freenode /#centos的声誉)与我分享了他的方法:

diff -Naur dir1/ dir2

包括最终目录的正斜杠无关紧要。

此外,该-u选项似乎在某些较旧/服务器版本的diff上不可用。

差异的区别:

# diff -Nar /tmp/dir1 /tmp/dir2/
diff -Nar /tmp/dir1/file /tmp/dir2/file
28a29
> TEST

# diff -qr /tmp/dir1/ /tmp/dir2/
Files /tmp/dir1/file and /tmp/dir2/file differ

2
因此,--new-file/-N这使得diff --text/-a会将丢失的文件视为空文件,并使其将所有二进制输入都视为文本。我看不到这种特殊用例的好处。
phk

4

Diffoscope是一个很棒的基于命令行的目录diff工具。

我特别喜欢它可以扩散文件中:

它将递归解压缩各种档案,并将各种二进制格式转换为更易于阅读的形式以进行比较。它可以轻松地比较两个tarball,ISO图像或PDF。

它不仅会告诉您哪些文件不同,而且还会告诉您它们如何不同。


4

要找到差异,请使用以下命令:

diff -qr dir1/ dir2/

-r也会区分所有子目录 -q告诉diff仅在文件不同时报告。

diff  --brief dir1/ dir2/

--brief将显示目录中存在的文件。

要不然

我们可以使用Meld,它将在图形窗口中显示其易于发现的差异。

meld  dir1/ dir2/

2
--brief-q是相同的选项。您的陈述听起来像它们是不同的,但不是。
伊莱贾·林恩

2

您也可以使用Rsyncfind。对于find

find $FOLDER -type f | cut -d/ -f2- | sort > /tmp/file_list_$FOLDER

但是具有相同名称和相同子文件夹但具有不同内容的文件将不会显示在列表中。

如果你是GUI的球迷,你可以检查合并@Alexander提及。它在Windows和Linux中都可以正常工作。


1

报告dirA和dirB之间的差异,同时更新/同步。

rsync -auv <dirA> <dirB>

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.