给定两个目录树,如何找出哪些文件有所不同?

Man*_*qui 743 unix linux bash shell diff

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

diff -r dir1/ dir2/
Run Code Online (Sandbox Code Playgroud)

这准确地输出了相应文件之间的差异.我有兴趣只获取内容不同的相应文件列表.我假设这只是一个传递命令行选项的问题diff,但我在手册页上找不到任何内容.

有什么建议?

Mar*_*ser 1069

你说Linux,所以你运气好了(至少它应该可用,不确定何时添加):

diff --brief --recursive dir1/ dir2/ # GNU long options
diff -qr dir1/ dir2/ # common short options
Run Code Online (Sandbox Code Playgroud)

应该做你需要的.

如果您还想查看任一目录中可能不存在的文件的差异:

diff --brief --recursive --new-file dir1/ dir2/ # GNU long options
diff -qrN dir1/ dir2/ # common short options
Run Code Online (Sandbox Code Playgroud)

  • 注意:这也适用于MacOS X(Yosemite). (22认同)
  • 尼斯.但是更短的是`diff -qr dir1/dir2 /`和我的扩展版本到`diff -qr dir1/dir2/| grep'不同' (11认同)
  • @MikeMaxwell 它需要是`--brief`。`-brief` 被解释为 `-b -r -i -e -f`,换言之,作为一组标志而不是作为单个选项。 (9认同)
  • 根据`man ps`,`-` 选项被称为“UNIX 选项”,而`--` 选项被称为“GNU 长选项”。`如果它使用任何选项,你应该让每个程序都接受长选项,因为这需要很少的额外工作并帮助初学者记住如何使用该程序。`来源:https://www.gnu.org/software/libc/manual/ html_node/Getopt-Long-Options.html,还有 https://www.google.com/search?q=gnu+long+options (3认同)
  • @skv不完全是原始问题所要求的,但更新答案以适应这个问题. (2认同)
  • @daboross:哇,我一直在使用Unix / Linux,但我从未意识到'-'和'-'之间没有区别。(我不认为开始时就存在“-”。)谢谢您的解释! (2认同)

FPC*_*FPC 283

我使用的命令是:

diff -qr dir1/ dir2/
Run Code Online (Sandbox Code Playgroud)

它与马克的完全相同:)但是他的回答让我困扰,因为它使用了不同类型的旗帜,它让我看了两次.使用Mark的更详细的标志,它将是:

diff  --brief --recursive dir1/ dir2/
Run Code Online (Sandbox Code Playgroud)

当其他答案完全可以接受时,我为发布而道歉.无法阻止自己...努力减少迂腐.

  • ..所以它是否有意义tu不同的答案只是一个不同的味道?恕我直言!是否有意义将两个答案结合在一致的答案中?是!;) (9认同)
  • 完全欣赏一致性 - 但不要感到难过; 我也赞成了Mark的答案;) (3认同)
  • @ kramer65 - 它与"--brief"相同,但我想你想知道为什么q?或许快点?根据手册页,"-b"取"忽略空白量的变化". (3认同)
  • @ kramer65我相信`q`代表`quiet`,通常意味着更简洁. (3认同)

Ala*_*ter 99

我喜欢使用git diff --no-index dir1/ dir2/,因为它可以显示颜色的差异(如果你在git配置中设置了该选项),并且因为它显示了使用"less"的长分页输出中的所有差异.

  • 整齐.谁会猜到git可以区分任意目录,而不仅仅是针对其文件的repo? (24认同)
  • 如果你比较(像我一样)2个dirs作为单独的git项目/ repos,那么你需要在http://stackoverflow.com/a/1792477/473390上添加`--no-index`.我已经更新了@ alan-porter的答案. (4认同)
  • Perl脚本[colordiff](http://www.colordiff.org/)在这里非常有用,可以与svn和普通diff一起使用. (2认同)

小智 33

这两个命令基本上要求的是:

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
Run Code Online (Sandbox Code Playgroud)

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

当目录驻留在两个单独的驱动器上时,diff优于rsync.但是当比较的两个目录在同一个驱动器上时,rsync会更快.这是因为diff在两个目录上并行放置几乎相等的负载,从而最大化两个驱动器的负载.

rsync在实际比较它们之前计算大块中的校验和.它将i/o操作分组为大块,并在单个驱动器上进行更有效的处理.

  • 我建议首先放置`--dry-run`,以免意外忘记它. (8认同)
  • rsync不仅对单个驱动器上的文件更快,而且允许比较子目录中的文件,例如`rsync --options/usr/bin/var/sbin/lib/old_root`将有效地比较当前的根`/`(通过指定其中的所有子目录)和`/ old_root`(包含例如`/`的一些旧备份),这是`diff -r`无法做到的.如果您假设具有相同大小,权限和时间戳的文件可能没有更改,则省略`--checksum`将为您提供**极快**(如果不是这样)检查哪些文件可能已更改. (3认同)
  • 如果您需要将本地目录与可通过 ssh 访问的远程目录进行比较,则“rsync”解决方案非常有用 (3认同)
  • “--delete”和“rsync”的目的是什么? (2认同)
  • --delete的目的是删除destination-dir中不存在(不再存在)source-dir中的现有文件 (2认同)
  • 在这种情况下(使用`--dry-run`标志)没有真正删除,`rsync`只打印哪些文件在dir1但不在dir2 (2认同)

Ale*_*der 19

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

meld dir1/ dir2/

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

  • 尼斯.我写了一个简单的perl脚本来对树进行比较,但我遇到了限制.这似乎是门票. (2认同)
  • @Alexander - 在这种情况下,我发现 `meld <(find dir1 -ls ) <(find dir2 -ls)` 使用 bash 进程替换效果很好。(zsh 的 `=(command)` 效果更好。) (2认同)

tod*_*dsm 9

频道同胞'账单'(freenode /#centos成名)与我分享他的方法:

diff -Naur dir1/ dir2
Run Code Online (Sandbox Code Playgroud)

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

此外,似乎该-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
Run Code Online (Sandbox Code Playgroud)

  • 这就是`--new-file / -N`,它使diff认为丢失的文件为空,而`--text / -a`则使它将所有二进制输入都视为文本。我看不到这种特殊用例的好处。 (2认同)

Jav*_*eel 5

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

diff -qr dir1/ dir2/
Run Code Online (Sandbox Code Playgroud)

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

diff  --brief dir1/ dir2/
Run Code Online (Sandbox Code Playgroud)

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

要不然

我们可以使用 Meld,它会在图形窗口中显示,很容易找到差异。

meld  dir1/ dir2/
Run Code Online (Sandbox Code Playgroud)

  • `--brief` 和 `-q` 是相同的选项。您的陈述听起来好像它们不同,但实际上并非如此。 (3认同)