给定两个目录树,我如何找出哪些文件因内容而异? [关闭]
Posted
技术标签:
【中文标题】给定两个目录树,我如何找出哪些文件因内容而异? [关闭]【英文标题】:Given two directory trees, how can I find out which files differ by content? [closed] 【发布时间】:2011-06-27 05:30:42 【问题描述】:如果我想找到两个目录树之间的差异,我通常只执行:
diff -r dir1/ dir2/
这会准确输出相应文件之间的差异。我只想获取内容不同的相应文件的列表。我认为这只是将命令行选项传递给diff
的问题,但我在手册页上找不到任何内容。
有什么建议吗?
【问题讨论】:
How to compare differences between directories (linux) 的副本 对于其中一个目录,如何只获取另一个目录中多余的文件/目录? 在 unix(不是 linux)上使用dircmp
命令
【参考方案1】:
试试:
diff --brief --recursive dir1/ dir2/
或者,使用短标志-qr
:
diff -qr dir1/ dir2/
如果您还想查看两个目录中可能不存在的文件的差异:
diff --brief --recursive --new-file dir1/ dir2/ # with long options
diff -qrN dir1/ dir2/ # with short flag aliases
【讨论】:
不错。但更短的是diff -qr dir1/ dir2/
,而我的扩展版本是diff -qr dir1/ dir2/ | grep ' differ'
@skv 不完全是原始问题所问的,但也更新了答案以适应这个问题。
@MikeMaxwell 必须是--brief
。 -brief
被解释为 -b -r -i -e -f
,换句话说,是一组标志,而不是单个选项。
@daboross:哇,我使用 Unix/Linux 已经有很长时间了,但我从来没有意识到 '--' 和 '-' 之间有这种区别。 (我不认为在我开始时存在'--'。)感谢您的解释!
根据man ps
,-
选项被称为“UNIX 选项”,--
选项被称为“GNU 长选项”。 You should make every program accept long options if it uses any options, for this takes little extra work and helps beginners remember how to use the program.
来源:gnu.org/software/libc/manual/html_node/Getopt-Long-Options.html,还有google.com/search?q=gnu+long+options【参考方案2】:
我使用的命令是:
diff -qr dir1/ dir2/
这和 Mark 的完全一样 :) 但是他的回答让我很困扰,因为它使用了不同的 types 标志,这让我看了两眼。使用 Mark 更详细的标志将是:
diff --brief --recursive dir1/ dir2/
当其他答案完全可以接受时,我很抱歉发帖。无法阻止自己......努力减少迂腐。
【讨论】:
非常欣赏一致性——但不要难过;我也赞成马克的回答;) ..所以你用不同的口味提出不同的答案有意义吗?恕我直言,不!将两个答案组合成一个一致的答案是否有意义?是的! ;) 只是一个问题;q
代表什么?它是某物的缩写吗?我找不到q
.. 背后的任何逻辑。
@kramer65 - 它与“--brief”相同,但我想你想知道为什么是 q?也许是为了快?根据手册页,“-b”被“忽略空白数量的变化”所采用。
@kramer65 我相信q
代表quiet
,通常意味着不那么冗长。【参考方案3】:
我喜欢使用git diff --no-index dir1/ dir2/
,因为它可以显示颜色的差异(如果您在 git 配置中设置了该选项)并且因为它使用“less”显示了长页面输出中的所有差异。
【讨论】:
整洁。谁会猜到 git 可以区分任意目录,而不仅仅是针对其文件的 repo? Perl script colordiff在这里非常有用,可以和svn和普通diff一起使用。 如果您(像我一样)将 2 个目录作为单独的 git 项目/repos 进行比较,那么您需要在 ***.com/a/1792477/473390 上添加更多--no-index
。我已经更新了@alan-porter 的答案。
我喜欢这个,我还发现如果你在命令行中添加--name-status
,它只会显示带有“M/A/D”标志的文件名列表,用于修改/添加/已删除状态。
这两个目录实际上都包含 .git 文件夹,我怎样才能将它从比较中排除?【参考方案4】:
使用rsync
:
rsync --dry-run --recursive --delete --links --checksum --verbose /dir1/ /dir2/ > dirdiff_2.txt
或者,使用diff
:
diff --brief --recursive --no-dereference --new-file --no-ignore-file-name-case /dir1 /dir2 > dirdiff_1.txt
它们在功能上是相同的,但性能可能会有所不同,具体取决于:
如果目录在同一个驱动器上,rsync 会更快。 如果目录位于两个单独的驱动器上,则 diff 更快。这是因为 diff 在两个目录上并行加载几乎相等的负载,从而最大化两个驱动器上的负载。 rsync 在实际比较它们之前计算大块的校验和。这会将 i/o 操作分组为大块,当事情发生在单个驱动器上时,可以提高处理效率。
【讨论】:
rsync 不仅对于单个驱动器上的文件更快,而且还允许比较子目录中的文件,例如rsync --options /usr /bin /var /sbin /lib /old_root
将有效地比较当前根目录/
(通过指定其中的所有子目录)和/old_root
(例如包含 /
的一些旧备份),这是 diff -r
无法做到的。如果您假设具有相同大小、权限和时间戳的文件可能没有更改,则省略 --checksum
将为您提供极快(如果不是这样的话)检查哪些文件可能已更改。
--delete
和 rsync
的目的是什么?
--delete 的目的是删除目标目录中的现有文件,这些文件(不再)存在于源目录中
在这种情况下(带有--dry-run
标志)没有真正删除任何内容,rsync
只打印哪些文件在 dir1 而不是在 dir2
我建议始终将--dry-run
放在首位,以免意外忘记它。【参考方案5】:
Meld 也是比较两个目录的好工具:
meld dir1/ dir2/
Meld 有许多用于比较文件或目录的选项。如果两个文件不同,很容易进入文件比较模式并查看确切的差异。
【讨论】:
不错。我编写了一个简单的 perl 脚本来对树进行比较,但我遇到了限制。这似乎是票。 唯一的问题是它不适合编写脚本,因为它是一个图形应用程序。但是,如果您不介意 GUI,那就太好了!谢谢。 我发现meld
如果在大目录上使用会变得非常缓慢。有什么东西可以更好地处理大目录吗?
@Popup,我不知道。不过,您可以通过以下方式找到不同的文件名:find dir1 dir2 | cut -d/ -f2- | sort | uniq --unique
@Alexander - 在这种情况下,我发现meld <(find dir1 -ls ) <(find dir2 -ls)
工作得很好,使用 bash 进程替换。 (zsh 的 =(command)
效果更好。)【参考方案6】:
频道同胞“billings”(freenode/#centos 名气)与我分享了他的方法:
diff -Naur dir1/ dir2
包含最终目录正斜杠无关紧要。
此外,-u
选项似乎在某些较旧/服务器版本的 diff 上不可用。
diffs的区别:
# 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
【讨论】:
这就是--new-file/-N
,这使得 diff 认为丢失的文件是空的,--text/-a
导致它认为所有二进制输入都是文本。我没有看到这个特定用例的好处。【参考方案7】:
要查找差异,请使用以下命令:
diff -qr dir1/ dir2/
-r 也会区分所有子目录 -q 告诉 diff 仅在文件不同时报告。
diff --brief dir1/ dir2/
--brief 将显示目录中存在的文件。
否则
我们可以使用 Meld,它会在图形窗口中显示它很容易找到差异。
meld dir1/ dir2/
【讨论】:
--brief
和 -q
是同一个选项。您的陈述听起来像是不同的,但实际上并非如此。【参考方案8】:
Diffoscope 是一个很棒的基于命令行的目录比较工具。
我特别喜欢它可以区分到个文件:
它将递归地解压多种档案并将各种二进制格式转换为更易于阅读的形式以进行比较。它可以很容易地比较两个 tarball、ISO 图像或 PDF。
它不仅会告诉您哪些文件不同,还会告诉您它们有何不同。
【讨论】:
【参考方案9】:您可以also 使用Rsync
和find
。对于find
:
find $FOLDER -type f | cut -d/ -f2- | sort > /tmp/file_list_$FOLDER
但同名、同一个子文件夹但内容不同的文件将不会显示在列表中。
如果您是 GUI 的粉丝,您可以查看@Alexander 提到的Meld。它在 windows 和 linux 上都可以正常工作。
【讨论】:
【参考方案10】:报告 dirA 和 dirB 之间的差异,同时更新/同步:
rsync -auv <dirA> <dirB>
【讨论】:
虽然它可能有效,但使用rsync
会增加一层复杂性,因为现在您需要这种依赖关系。这是一个不错的附属品,但在我看来,它使用的不仅仅是 linux。
@Lomefin 我看不出rsync
比diff
少Linux。 @Kickaha 在启动该命令之前,您肯定需要备份目标目录。以上是关于给定两个目录树,我如何找出哪些文件因内容而异? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章