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="'{' 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 错误,这就是我删除行号然后执行差异的原因。但是一旦我知道添加了哪些错误,我就需要与该错误关联的行号。
这看起来像 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"/>
我有两个文件想要比较。第一个文件如下所示:
<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="'{' 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 错误,这就是我删除行号然后执行差异的原因。但是一旦我知道添加了哪些错误,我就需要与该错误关联的行号。
这看起来像 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"/>