diff:仅比较文件并忽略子目录

时间:2015-05-25 21:52:38

标签: linux bash shell command-line diff

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

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

谢谢!

2 个答案:

答案 0 :(得分:2)

如果只是对目录名称diff进行操作而不添加-r选项,GNU diff将报告不同的子目录名称但不会重复进入差异他们的内容。

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

如果你想过滤掉目录名,可以通过一个脚本来管道差异,该脚本查找以&#34开头的行;只有"并且忽略那些在"之后的部分:"是目录名称。 diff的输出格式可以合理预测。可以轻松解析的一件事是内容(差异)缩进一个空格,允许使用第一列标记

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

#!/usr/bin/perl -w

use strict;

die "usage: $0 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假装比较的每一方都存在,因此它表示&#34;公共子目录&#34;对于每个子目录。

答案 1 :(得分:2)

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

假设您在父目录中;你有一个像这样的结构,你想要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&#39; -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

希望这会有所帮助:)