Perl - 在差异期间忽略某些事情,但之后再添加它们

时间:2015-12-22 10:58:54

标签: regex perl diff

我有两个我想要差异的文件。第一个文件如下所示:

<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="&apos;{&apos; 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="&apos;{&apos; is not preceded with whitespace." source="com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAroundCheck"/>
    <error line="15" column="21" severity="info" message="Variable &apos;a&apos; should be declared final." source="com.puppycrawl.tools.checkstyle.checks.coding.FinalLocalVariableCheck"/>
    <error line="15" column="25" severity="info" message="&apos;5&apos; is a magic number." source="com.puppycrawl.tools.checkstyle.checks.coding.MagicNumberCheck"/>
    </file>
    </checkstyle>

我只想知道新的Checkstyle错误,这就是我删除行号然后执行差异的原因。但是一旦我知道添加了哪些错误,我就需要与该错误相关联的行号。

1 个答案:

答案 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"/>