我有以下文件( file1 )
更多文件1
<?xml version="1.0" encoding="UTF-8"?>
<apps>
<app name="UAT/ECC/Global/MES/1206/MRP-S23" ear="UAT/ECC/Global/MES/1206/MRP-S23.ear" xml="UAT/ECC/Glal/ME/120/MRP- S23.xml"/>
<app name="OQ/ediedbn/adSFSF/adSFSF-CL" ear="OQ/ebn/aSF/adSF- CL.ear" xml="OQ/ediedbn/adSFSF/adSSF-CL.xml"/>
<app name="OQ/ediedbn/adaEBS/adOrBS-HR-CL" ear="OQ/ediedbn/adOraS/araEBS-HR-CL.ear" xml="OQ/eddbn/aOraEBS/adOEBS- HR-CL.xml"/>
<app name="UAT/CZ/LIMS/T068_01/LIMS-QA-S03" ear="UAT/CZ/LIS/T068_01/LIS-QA-S03.ear" xml="UAT/CZ/LIMS/T068_01/LIMS-QA-S03.xml"/>
.
.
.
这是我需要在 file1 上匹配的示例行
更多文件2
OQ-63/ECC/Glal/Interny/Adapter_Services/adOraEBS-NA
OQ-63/ECC/Glal/MES/58,61/ECC-MRP-S20
OQ-63/ECC/Glbal/MES/CZ/adum-CZ-Adapter
OQ-63/EC/Glal/TI/Adaptvices/adTIS
为了匹配 file1 上 file2 中的行(并忽略反斜杠和其他不常见字符),perl oneliner 语法的最佳方法是什么?
我尝试过这个但不起作用
a="OQ-63/ECC/Glal/Interny/Adapter_Services/adOraEBS-NA"
perl -pe '/(^|\s)\Q$ENV{a}\E(\s|$)/' file1
答案1
您的尝试有几个问题:
- perl -pe 打印所有行 - 您需要删除不匹配的行,或者使用 -n 和显式打印
- 匹配的字符串前面有引号,但您检查 \s
- 为了进行测试,显示 file1 以及与 file2 匹配的一些行很有用:)
所以这会起作用:
a="UAT/CZ/LIMS/T068_01/LIMS-QA-S03" perl -ne '/"\Q$ENV{a}\E"/ && print' file1
要在一行中完成所有匹配,您可以执行以下操作:
perl -ne 'BEGIN { open(F2, shift); $re=join("|", map {chomp($_); "\"\Q${_}\E\"";} <F2>);} /$re/ && print' file2 file1
答案2
这就是 XML。正则表达式是一个不适合 XML,尽管它们看起来应该可以工作。
这是因为 XML 是上下文相关的,而正则表达式则不是。 XML 有一堆格式差异,它们在语义上是相同的,但与相同的正则表达式不匹配。
虽然 - 看起来您的“第二个文件”条目与示例中的第一个文件都不匹配。我猜测您想要匹配 XML 的“名称”字段。 (如果可以的话,您应该避免“匹配任何属性”)。
#!/usr/bin/perl
use strict;
use warnings;
#dumper is only needed for the 'print Dumper' line below
#for debugging. Both can safely be removed.
use Data::Dumper;
use XML::Twig;
open ( my $match_file, '<', 'file2' ) or die $!;
chomp ( my @matches = <$match_file> );
my %lookup = map { $_ => 1 } @matches;
#or if you want a more pithy one that IMO is a bit harder to understand.
#my %lookup = map { s/[\r\n]+//gr => 1 } <$match_file>;
print Dumper \%lookup;
my $twig = XML::Twig -> new -> parsefile ( 'file2' );
#xpath is XMLs equivalent of regex, but it's
#more suited to node and attribute matching.
foreach my $app ( $twig -> get_xpath ( '//app' ) ) {
$app -> print if $lookup{$app->att('name')};
#Alternatively extract a single field.
print "XML: ", $app -> att('xml'),"\n";
}
作为一个班轮?老实说,如果你愿意的话我不会两个都读取匹配项以及搜索/打印。
但对于单个元素,我可能会选择:
a="UAT/CZ/LIMS/T068_01/LIMS-QA-S03" perl -MXML::Twig -e 'XML::Twig -> new ( twig_handlers => { 'app' => sub { $_ -> print if $_ -> att('name') eq $ENV{'a'} } } ) -> parse ( { do {local $/; <> } )'
但老实说 - 我会坚持把它写成“长形式”,而不是试图在一行中施展一些魔法 - 如果你尝试阅读全部你的模式,你最终会得到一个低效的算法,如果你尝试这样做全部然后你在同一个衬垫中进行双文件读取和数据结构,这太混乱了。