Regex 在Perl脚本中创建哈希的步骤
创建下面散列的方法是我的文件的内容,当我打开包含下面内容的输入文件时,我们希望从表中grep一些数据,以便创建下面模式的散列Regex 在Perl脚本中创建哈希的步骤,regex,perl,file,hash,Regex,Perl,File,Hash,创建下面散列的方法是我的文件的内容,当我打开包含下面内容的输入文件时,我们希望从表中grep一些数据,以便创建下面模式的散列 { 'Golden' => { 'PT' => 80, 'po' => 43, 'DFF' => 139145, 'DLAT' => 276,
{
'Golden' => {
'PT' => 80,
'po' => 43,
'DFF' => 139145,
'DLAT' => 276,
'Z' => 4,
'BBOX' => 833,
'Total' => 140387
},
'Foo Bar' => {
'PT' => 80,
'po' => 43,
'DFF' => 139145,
'DLAT' => 276,
'Z' => 4,
'BBOX' => 833,
'Total' => 140387
}
};
文件内容
样本1
Mapped points: SYSTEM class
Mapped points PI PO BBOX Total
Golden 86 43 833 140387
Revised 86 43 833 140387
样本2
Mapped points: SYSTEM class
Mapped points PI PO DFF DLAT Z BBOX Total
Golden 86 43 139145 276 4 833 140387
Revised 86 43 139145 276 4 833 140387
她就是我被困的地方
if ($line =~ m/^Mapped points: SYSTEM class$/){
$var = "golden_mapped-points_PI";
$hash{$var} = $6;
next unless $line = <$filehandle> and $line =~ /^Mapped points PI PO DFF DLAT Z BBOX Total $/;
}
if($line=~m/^映射点:系统类$/){
$var=“golden\u-points\u PI”;
$hash{$var}=$6;
下一步,除非$line=和$line=~/^映射点PI PO DFF DLAT Z BBOX总计$/;
}
此外,在不同的输入文件编号列中可能会发生变化,例如,它可能只有PI和PO。在这种情况下,我也不知道如何处理输入文件。我仔细考虑并找到了解决方案!!我知道这不是最好的解决方案,我请求你为我提供最好的解决方案
cat > test.pl
#!/usr/bin/perl
use strict;
use warnings;
while(<DATA>){
my $line = $_;
if ($line =~ m/^Mapped points: SYSTEM class$/){
next unless $line = <DATA> and $line =~ /^Mapped points/;
my @arr = split(' ',$line);
next unless $line = <DATA>;
my @golden_arr = split(' ',$line);
my $size1 = @golden_arr;
for(my $i = 1;$i < $size1 ;$i++){
my $var = "Golden_".$arr[$i+1];
print "$var, $golden_arr[$i]\n";
}
next unless $line = <DATA>;
my @revised_arr = split(' ',$line);
my $size2 = @revised_arr;
for(my $i = 1;$i < $size2 ;$i++){
my $var = "Revised_".$arr[$i+1];
print "$var, $revised_arr[$i]\n";
}
}
}
__DATA__
Mapped points: SYSTEM class
Mapped points PI PO DFF DLAT Z BBOX Total
Golden 86 43 139145 276 4 833 140387
Revised 86 43 139145 276 4 833 140387
perl test.pl
Golden_PI, 86
Golden_PO, 43
Golden_DFF, 139145
Golden_DLAT, 276
Golden_Z, 4
Golden_BBOX, 833
Golden_Total, 140387
Revised_PI, 86
Revised_PO, 43
Revised_DFF, 139145
Revised_DLAT, 276
Revised_Z, 4
Revised_BBOX, 833
Revised_Total, 140387
cat>test.pl
#!/usr/bin/perl
严格使用;
使用警告;
while(){
我的$line=$\ux;
如果($line=~m/^映射点:系统类$/){
下一步,除非$line=和$line=~/^映射点/;
my@arr=分割(“”,$line);
下一步,除非$line=;
我的@golden_arr=分割(“”,$line);
我的$size1=@golden_arr;
对于(我的$i=1;$i<$size1;$i++){
我的$var=“Golden”..$arr[$i+1];
打印“$var,$golden_arr[$i]\n”;
}
下一步,除非$line=;
my@Revisited_arr=拆分(“”,$line);
my$size2=@REVIDED_arr;
对于(我的$i=1;$i<$size2;$i++){
我的$var=“修订”..$arr[$i+1];
打印“$var$revisited\u arr[$i]\n”;
}
}
}
__资料__
映射点:系统类
映射点PI PO DFF DLAT Z BBOX总计
黄金86 43 139145 276 4 833 140387
修订86 43 139145 276 4 833 140387
perl test.pl
金玉皮,86岁
金乌坡,43岁
戈尔登迪福,139145
金杜德拉特,276
戈尔登兹,4
金盒子,833
Golden_总计,140387
修订版_PI,86
经修订的_PO,43
修订版(英国)DFF,139145
修订版,第276页
修订版(四)
修订版_BBOX,833
修订总数,140387
有更好的解决方案吗?您需要保留标题行的副本,因为标题是内部哈希项的键。一旦开始处理数据行,就需要将第一个项作为外部散列项的键(行的一种标签)移开。一旦这些信息被存储起来,你的标题和数据就会“排成一行”
#/usr/bin/env perl
使用v5.12;
使用数据::转储程序;
my$start_re='映射点:系统类';
我的$headers_re='Mapped\s+points\s+';
我的%u散列;
#找到起跑线
while(){last if/$starting_re/}
#读一行。希望它是标题行
#把它分成几块,然后储存起来,供以后使用
我的@标题;
我的$headers_line=;
如果($headers\u line=~/$headers\u re(.*)/x){
@标题=拆分“”,1美元;
}
否则{
说“不明白标题行。”;
出口1;
}
#处理剩余的每一行
而(){
#拆分数据行并移开
#用作线条标签的第一块
my@data=split“”,$;
my$label=shift@data;
#初始化新的内部哈希和索引变量
我的%inner_哈希=();
我的$index=0;
#迭代构建散列的数据段
for(@data){
$internal_hash{$headers[$index]}=$\u;
$index++;
}
#或者,使用散列切片构建它
#@internal_hash{@headers}=@data;
#通过在外部哈希中创建一个条目
#引用我们的内部散列
$outer\u hash{$label}=\%inner\u hash;
}
说出转储程序(\%outer\u散列);
出口0;
我想出了一个使用unpack的解决方案。它处理不同文件中任意数量的列
#!/usr/bin/perl
use strict;
use warnings;
my %data;
my ($len, @hdrs);
my (@lengths, $template);
while (<DATA>) {
next if 1 .. /^Mapped points:/;
s/\s+$//; # safe 'chomp' (if there are spaces at end of string)
if (s/^(Mapped points\s+)//) {
$len = length $1;
@hdrs = split;
# lengths of all but the last (Total) field
@lengths = map {length} /(\S+\s+)/g;
# add 'A*' at the end to capture the 'Total' field
$template = join("", "A$len", map {'A'. $_} @lengths) . "A*";
}
else {
my ($key, @rest) = unpack $template;
my %temp;
@temp{ @hdrs } = @rest;
$data{$key} = \%temp;
}
}
use Data::Dumper; print Dumper \%data;
__DATA__
Mapped points: SYSTEM class
Mapped points PI PO DFF DLAT Z BBOX Total
Golden 86 43 139145 276 4 833 140387
Revised 86 43 139145 276 4 833 140387
你需要创建一个新的模型,并澄清你的问题。
#!/usr/bin/perl
use strict;
use warnings;
my %data;
my ($len, @hdrs);
my (@lengths, $template);
while (<DATA>) {
next if 1 .. /^Mapped points:/;
s/\s+$//; # safe 'chomp' (if there are spaces at end of string)
if (s/^(Mapped points\s+)//) {
$len = length $1;
@hdrs = split;
# lengths of all but the last (Total) field
@lengths = map {length} /(\S+\s+)/g;
# add 'A*' at the end to capture the 'Total' field
$template = join("", "A$len", map {'A'. $_} @lengths) . "A*";
}
else {
my ($key, @rest) = unpack $template;
my %temp;
@temp{ @hdrs } = @rest;
$data{$key} = \%temp;
}
}
use Data::Dumper; print Dumper \%data;
__DATA__
Mapped points: SYSTEM class
Mapped points PI PO DFF DLAT Z BBOX Total
Golden 86 43 139145 276 4 833 140387
Revised 86 43 139145 276 4 833 140387
$VAR1 = {
'Golden' => {
'Total' => '140387',
'BBOX' => '833',
'Z' => '4',
'PO' => '43',
'DLAT' => '276',
'DFF' => '139145',
'PI' => '86'
},
'Revised' => {
'Total' => '140387',
'BBOX' => '833',
'Z' => '4',
'PO' => '43',
'DLAT' => '276',
'DFF' => '139145',
'PI' => '86'
}
};