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

Perl - ignoring certain things during a diff, but adding them back afterwards

我有两个文件想要比较。第一个文件如下所示:

<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"...

我想在 diff 期间忽略行号,所以我使用一些正则表达式将所有行号设置为相同。所以现在文件 #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 returns 输出,我将需要为 diff 输出的每个元素取回行号(即,在这种情况下,我将要取回 [=16 的行号=])。有谁知道如何做到这一点?谢谢你的帮助。

编辑: 实际使用的文件是写入文件的 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 错误,这就是我删除行号然后执行差异的原因。但是一旦我知道添加了哪些错误,我就需要与该错误关联的行号。

这看起来像 XML,所以我将继续假设它实际上是 XML。如果那不是一个有效的假设,那么……这将行不通。但是写那些日志文件的人是造假的坏人XML。

所以据我了解 - 您想从两个文件中提取唯一的 'message' 属性,然后挑选出 'missing' 的属性?

像这样的东西就可以了。

#!/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\']");
}

这比较 just 消息内容 - 您的示例表明它是唯一的(并在其他结构中的任何位置搜索匹配消息)。这可能不完全是您所追求的,但类似的技术应该能够满足您的需求。

以下更新:

#!/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,因为它假定第一个文件中的错误是第二个文件中错误的子集。 (但反之则不然)。但它应该仅基于 'source'

来打印新的错误行

使用您的样本数据输出:

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