解析数据并适合 Hash 给出了预期的结果
Parse data and fit in Hash gives not expected result
我有数据需要解析并打印在屏幕上。
这是数据和我的脚本:
输入数据:
__DATA__
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1
Ref : [Network=Europe,Network=Ireland,Node=S01,SecAnt=1]
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1
resBy : [Network=Europe,Network=Ireland,Node=S01,Cell=1]
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2
resBy : [Network=Europe,Network=Ireland,Node=S01,Cell=1]
脚本:
#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;
use List::Util qw /uniq/;
my ($node, $item, %hash1, %hash2, %hash3);
while (my $line = <DATA>){
chomp $line;
if ($line =~ m/^\s*Node :\s*(.*?)(,Car=\d+)?\s*$/) {
$node = ;
} elsif ($line =~ m/^\s*Ref :\s*\[*(.*?)\]*\s*$/) {
$hash1{$node} = [ split /, /, ] ;
($node, $item) = "";
} elsif ($line =~ m/^\s*resBy :\s*\[*(.*?)\]*\s*$/) {
$hash2{$node} = [ split /, /, ];
($node, $item) = "";
}
}
foreach my $sec (keys %hash1){
foreach my $ant (@{$hash1{$sec}}) {
push @{$hash3{$ant}}, $sec;
}
}
print "Hash3:\n". Dumper(\%hash3);
my $i = 0;
foreach my $sec_ant (sort keys %hash3){
++$i;
print "sec_ant_$i:$sec_ant\n";
print "car_$i:", join('###', uniq @{$hash3{$sec_ant}}), "\n";
}
这是我当前的输出:
Hash3:
$VAR1 = {
'Network=Europe,Network=Ireland,Node=S01,SecAnt=1' => [
'Network=Europe,Network=Ireland,Node=S01,Sec=1'
]
};
sec_ant_1:Network=Europe,Network=Ireland,Node=S01,SecAnt=1
car_1:Network=Europe,Network=Ireland,Node=S01,Sec=1
预期结果:
Hash3:
$VAR1 = {
'Network=Europe,Network=Ireland,Node=S01,SecAnt=1' => [
'Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1',
'Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2',
]
};
sec_ant_1:Network=Europe,Network=Ireland,Node=S01,SecAnt=1
car_1:Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1###Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2
因为它应该查找没有 Car
数据的 Node
值,并选择相应的 SecAnt
数据。并且根据 Node
值,需要使用 resBy
的 Node
数据来选择相应的 Sec+Car
数据(来自 hash2
)。我该怎么做?
我可以建议使用 $/
作为记录分隔符吗?这将使这项任务更容易。我认为您使用复合条件使事情过于复杂。怎么样:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use List::Util qw /uniq/;
my %results;
#current 'parent' node
my $current;
#parse input as paragraphs - blank line delimited.
$/ = '';
#iterate the data - we don't bother setting `$line` because it's not necessary
#as all data is extracted via pattern matches against implicit $_
while (<DATA>) {
#if we're a Ref stanza, set the current node.
if (m/Ref : (.*)/) {
$current = ;
}
#if we're a resBy stanza, insert the node into the parent
#using push, so we don't overwrite.
if (m/resBy/) {
m/Node : (.*)/;
push( @{ $results{$current} }, );
}
}
print Dumper \%results;
my $count;
foreach my $sec_ant ( sort keys %results ) {
++$count;
print "sec_ant_${count}:$sec_ant\n";
print "car_${count}:", join( '###', uniq @{ $results{$sec_ant} } ), "\n";
}
__DATA__
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1
Ref : [Network=Europe,Network=Ireland,Node=S01,SecAnt=1]
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1
resBy : [Network=Europe,Network=Ireland,Node=S01,Cell=1]
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2
resBy : [Network=Europe,Network=Ireland,Node=S01,Cell=1]
我们正在使用 $/
设置 'paragraph' 模式,因此 while 循环的每次迭代都以空行分隔。
我们从每个记录中提取 'Node' 细节,然后匹配 Ref
或 resBy
来决定如何处理节点的其余部分 - 处理 Ref
节点作为父节点(每次遇到一个节点时设置 $current
)和 resBy
作为子节点,将值推入散列的 $current
分支。
这会产生请求的输出:
$VAR1 = {
'[Network=Europe,Network=Ireland,Node=S01,SecAnt=1]' => [
'Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1',
'Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2'
]
};
sec_ant_1:[Network=Europe,Network=Ireland,Node=S01,SecAnt=1]
car_1:Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1###Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2
你表示有额外的数据 - 我只是想推断你的其余数据可能会是什么样子,所以这可能是错误的。
我有数据需要解析并打印在屏幕上。
这是数据和我的脚本:
输入数据:
__DATA__
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1
Ref : [Network=Europe,Network=Ireland,Node=S01,SecAnt=1]
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1
resBy : [Network=Europe,Network=Ireland,Node=S01,Cell=1]
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2
resBy : [Network=Europe,Network=Ireland,Node=S01,Cell=1]
脚本:
#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;
use List::Util qw /uniq/;
my ($node, $item, %hash1, %hash2, %hash3);
while (my $line = <DATA>){
chomp $line;
if ($line =~ m/^\s*Node :\s*(.*?)(,Car=\d+)?\s*$/) {
$node = ;
} elsif ($line =~ m/^\s*Ref :\s*\[*(.*?)\]*\s*$/) {
$hash1{$node} = [ split /, /, ] ;
($node, $item) = "";
} elsif ($line =~ m/^\s*resBy :\s*\[*(.*?)\]*\s*$/) {
$hash2{$node} = [ split /, /, ];
($node, $item) = "";
}
}
foreach my $sec (keys %hash1){
foreach my $ant (@{$hash1{$sec}}) {
push @{$hash3{$ant}}, $sec;
}
}
print "Hash3:\n". Dumper(\%hash3);
my $i = 0;
foreach my $sec_ant (sort keys %hash3){
++$i;
print "sec_ant_$i:$sec_ant\n";
print "car_$i:", join('###', uniq @{$hash3{$sec_ant}}), "\n";
}
这是我当前的输出:
Hash3:
$VAR1 = {
'Network=Europe,Network=Ireland,Node=S01,SecAnt=1' => [
'Network=Europe,Network=Ireland,Node=S01,Sec=1'
]
};
sec_ant_1:Network=Europe,Network=Ireland,Node=S01,SecAnt=1
car_1:Network=Europe,Network=Ireland,Node=S01,Sec=1
预期结果:
Hash3:
$VAR1 = {
'Network=Europe,Network=Ireland,Node=S01,SecAnt=1' => [
'Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1',
'Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2',
]
};
sec_ant_1:Network=Europe,Network=Ireland,Node=S01,SecAnt=1
car_1:Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1###Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2
因为它应该查找没有 Car
数据的 Node
值,并选择相应的 SecAnt
数据。并且根据 Node
值,需要使用 resBy
的 Node
数据来选择相应的 Sec+Car
数据(来自 hash2
)。我该怎么做?
我可以建议使用 $/
作为记录分隔符吗?这将使这项任务更容易。我认为您使用复合条件使事情过于复杂。怎么样:
#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
use List::Util qw /uniq/;
my %results;
#current 'parent' node
my $current;
#parse input as paragraphs - blank line delimited.
$/ = '';
#iterate the data - we don't bother setting `$line` because it's not necessary
#as all data is extracted via pattern matches against implicit $_
while (<DATA>) {
#if we're a Ref stanza, set the current node.
if (m/Ref : (.*)/) {
$current = ;
}
#if we're a resBy stanza, insert the node into the parent
#using push, so we don't overwrite.
if (m/resBy/) {
m/Node : (.*)/;
push( @{ $results{$current} }, );
}
}
print Dumper \%results;
my $count;
foreach my $sec_ant ( sort keys %results ) {
++$count;
print "sec_ant_${count}:$sec_ant\n";
print "car_${count}:", join( '###', uniq @{ $results{$sec_ant} } ), "\n";
}
__DATA__
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1
Ref : [Network=Europe,Network=Ireland,Node=S01,SecAnt=1]
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1
resBy : [Network=Europe,Network=Ireland,Node=S01,Cell=1]
Node : Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2
resBy : [Network=Europe,Network=Ireland,Node=S01,Cell=1]
我们正在使用 $/
设置 'paragraph' 模式,因此 while 循环的每次迭代都以空行分隔。
我们从每个记录中提取 'Node' 细节,然后匹配 Ref
或 resBy
来决定如何处理节点的其余部分 - 处理 Ref
节点作为父节点(每次遇到一个节点时设置 $current
)和 resBy
作为子节点,将值推入散列的 $current
分支。
这会产生请求的输出:
$VAR1 = {
'[Network=Europe,Network=Ireland,Node=S01,SecAnt=1]' => [
'Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1',
'Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2'
]
};
sec_ant_1:[Network=Europe,Network=Ireland,Node=S01,SecAnt=1]
car_1:Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=1###Network=Europe,Network=Ireland,Node=S01,Sec=1,Car=2
你表示有额外的数据 - 我只是想推断你的其余数据可能会是什么样子,所以这可能是错误的。