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 .
如果您已经在区分两个特定的目录,那么我假设您知道它们的名称。在这种情况下,您需要动态确定的是每个目录中包含的子目录列表。
假设您在父目录中;你有这样的结构,你想区分 foo
和 bar
但你想排除 baz
和 quux
:
+-- foo/
| |-- baz/
| |
| +-- file.txt
|
+-- bar/
|-- quux/
|
+-- file.txt
使用find
:
find * -mindepth 1 -type d
生成 foo
和 bar
中的子目录列表:
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
希望这对您有所帮助:)
我正在尝试比较两个目录,每个目录都有一些文件和一个子目录。有什么办法可以 运行 区分这两个文件夹,但不能 运行 区分子目录?我试过使用 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 .
如果您已经在区分两个特定的目录,那么我假设您知道它们的名称。在这种情况下,您需要动态确定的是每个目录中包含的子目录列表。
假设您在父目录中;你有这样的结构,你想区分 foo
和 bar
但你想排除 baz
和 quux
:
+-- foo/
| |-- baz/
| |
| +-- file.txt
|
+-- bar/
|-- quux/
|
+-- file.txt
使用find
:
find * -mindepth 1 -type d
生成 foo
和 bar
中的子目录列表:
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
希望这对您有所帮助:)