diff:只比较文件,忽略子目录

diff: Only compare files and ignore subdirectories

我正在尝试比较两个目录,每个目录都有一些文件和一个子目录。有什么办法可以 运行 区分这两个文件夹,但不能 运行 区分子目录?我试过使用 diff -x'*/' foo bar,以及一些带有反斜杠的变体来转义它们,但没有骰子。

子目录的实际名称可以更改,这就是我不想指定确切名称模式的原因。

谢谢!

如果您只是对目录名称执行 diff,而不添加 -r 选项,GNU diff 将报告不同的子目录 names 但不会重复出现比较它们的内容。

这在 GNU diff 手册中有详细记录:4 Comparing Directories.

如果你想过滤掉目录名称,你 可以 通过一个脚本来查找以 "Only" 开头的行并忽略那些部分“:”之后是目录名。 diff 的输出格式是可以合理预测的。使解析变得容易的一件事是 content(差异)缩进了一个 space,允许将第一列用于 markup.

这是一个简单的 Perl 脚本,它依赖于 GNU diff 的 -N 选项的副作用来简化过滤(使用 3.0 版测试):

#!/usr/bin/perl -w

use strict;

die "usage: [=10=] sourcedir targetdir"
  unless ( $#ARGV == 1 and -d $ARGV[0] and -d $ARGV[1] );

open FP, "diff -u -N \"" . $ARGV[0] . "\" \"" . $ARGV[1] . "\" |"
  or die "diff: $!";
while (<FP>) {
    print unless ( $_ =~ /^Com/ );
}
close FP;

1;

-N 选项告诉 diff 假装比较的每一边都存在,所以它说 "Common subdirectories" for every subdirectory .

如果您已经在区分两个特定的目录,那么我假设您知道它们的名称。在这种情况下,您需要动态确定的是每个目录中包含的子目录列表。

假设您在父目录中;你有这样的结构,你想区分 foobar 但你想排除 bazquux:

+-- foo/
|     |-- baz/
|     |
|     +-- file.txt
|
+-- bar/
      |-- quux/
      |
      +-- file.txt

使用find:

find * -mindepth 1 -type d

生成 foobar 中的子目录列表:

foo/baz
bar/quux

此时您可以将其写入临时文件:

find * -mindepth 1 -type d > exclude.txt

然后使用 diff-X 标志,它允许您指定包含要从差异中排除的模式的文件。

但这不太可行,因为您需要从每个结果中切出父目录名称。我们可以使用 cut 来做到这一点:

find * -mindepth 1 -type d | cut -d'/' -f2 > exclude.txt

这会产生以下结果:

baz
quux

所以你现在可以使用:

diff -X exclude.txt foo bar

或者,如果您不想创建临时文件,您可以单行创建:

diff -uX <(find * -mindepth 1 -type d | cut -d'/' -f2) foo bar

希望这对您有所帮助:)