我有两个我想要差异的文件。第一个文件如下所示:
<error line="3" message="message 1"...
<error line="4" message="message 2"...
第二个看起来像这样:
<error line="4" message="message 1"...
<error line="5" message="message 2"...
<error line="5" message="message 3"...
我想忽略差异中的行号,所以我使用了一些正则表达式将所有行号设置为相同。所以现在文件#1看起来像这样:
<error line="." message="message 1"...
<error line="." message="message 2"...
文件#2看起来像这样:
<error line="." message="message 1"...
<error line="." message="message 2"...
<error line="." message="message 3"...
但是,一旦diff返回其输出,我将需要为diff输出的每个元素返回行号(即在这种情况下,我将需要返回<error line="." message="message 3"...
的行号)。有谁知道如何做到这一点?谢谢你的帮助。
修改 使用的实际文件是写入文件的Checkstyle输出。
文件1:
<checkstyle version="5.3">
<file name="d:\var\temp\cstemp\.\File1.java">
<error line="1" severity="warning" message="Missing a Javadoc comment." source="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck"/>
<error line="1" severity="warning" message="Missing package declaration."
</file>
</checkstyle>
文件2:
<checkstyle version="5.3">
<file name="d:\var\temp\cstemp\.\File1.java">
<error line="2" severity="warning" message="Missing a Javadoc comment." source="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck"/>
<error line="2" severity="warning" message="Missing package declaration." source="com.puppycrawl.tools.checkstyle.checks.coding.PackageDeclarationCheck"/>
<error line="10" column="9" severity="warning" message="Missing a Javadoc comment." source="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck"/>
<error line="10" column="35" severity="info" message="'{' is not preceded with whitespace." source="com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAroundCheck"/>
<error line="14" column="9" severity="warning" message="Missing a Javadoc comment." source="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck"/>
<error line="14" column="29" severity="info" message="'{' is not preceded with whitespace." source="com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAroundCheck"/>
<error line="15" column="21" severity="info" message="Variable 'a' should be declared final." source="com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck"/>
<error line="15" column="25" severity="info" message="'5' is a magic number." source="com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck"/>
</file>
</checkstyle>
我只想知道新的Checkstyle错误,这就是我删除行号然后执行差异的原因。但是一旦我知道添加了哪些错误,我就需要与该错误相关联的行号。
答案 0 :(得分:1)
这看起来像XML,所以我将继续假设它实际上是XML。如果这不是一个有效的假设,那么...这不会奏效。但是,那些编写这些日志文件的人是伪造XML的坏人。
据我所知 - 你想要提取独特的消息&#39;来自两个文件的属性,并选出那些缺少的文件&#39;?
这样的事情可以解决问题。
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $first = XML::Twig -> new -> parsefile ('samplec.xml');
my $second = XML::Twig -> new -> parsefile ('sampled.xml');
foreach my $error ( $second -> get_xpath('//error') ) {
my $message = $error -> att('message');
$error -> print unless $first -> get_xpath("//error[\@message=\'$message\']");
}
这比较消息内容上的 - 您的示例建议这是唯一的(并在其他任何位置搜索其他结构中的匹配消息)。这可能不是你所追求的,但类似的技术应该能够做你想要的。
更新后:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
use Data::Dumper;
my $first = XML::Twig -> new -> parsefile ('samplec.xml');
my $second = XML::Twig -> new -> parsefile ('sampled.xml');
my @first_errors = $first -> get_xpath('//error');
my @second_errors = $second -> get_xpath('//error');
my $first_err = shift ( @first_errors );
my $second_err = shift ( @second_errors );
while ( @first_errors or @second_errors ) {
if ( defined $first_err and $first_err -> att('source') eq $second_err -> att('source') ) {
## match
}
else {
#doesn't match, so we print
$second_err -> print;
print "\n";
}
$first_err = shift ( @first_errors );
$second_err = shift ( @second_errors );
}
我们在第一个和第二个文件中解析XML,并在我们去的时候迭代每个打印。注意 - 这不是严格的diff
,因为它假定第一个文件中的错误是第二个文件中错误的子集。 (但不是相反)。但它应该用于打印基于“源”的新错误行。
根据您的样本数据输出:
<error column="9" line="10" message="Missing a Javadoc comment." severity="warning" source="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck"/>
<error column="35" line="10" message="'{' is not preceded with whitespace." severity="info" source="com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAroundCheck"/>
<error column="9" line="14" message="Missing a Javadoc comment." severity="warning" source="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck"/>
<error column="29" line="14" message="'{' is not preceded with whitespace." severity="info" source="com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAroundCheck"/>
<error column="21" line="15" message="Variable 'a' should be declared final." severity="info" source="com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck"/>