哈希的键作为数组,匹配后将键值放入数组

问题描述 投票:0回答:2

我已经将显示的文件作为脚本的输入并创建了一个散列。我想在匹配后将键作为数组并将相应的键值放入该数组中。

我已经创建了哈希,但发现将键创建为数组并将其值创建到相应数组中的问题。非常感谢任何帮助。

预期输出如下

@school = (STRING_x, STRING_y, STRING_z,STRING_k)
@University = (STRING_a, STRING_b, STRING_c)s
@College = (STRING_d, STRING_e, STRING_f)

输入文件

begin_
No,59,Type:,School,Authors:,,,,
Local,config
0,0,0,STRING_x,256
1,0,1,STRING_y,256
2,0,2,STRING_z,256
3,0,3,STRING_k,256
end,,,,,

begin_
No,99,Type:,University,Authors:,,,
Local,config
0,0,0,STRING_a,64
0,0,0,STRING_b,64
0,0,0,STRING_c,64
end,,,,,

begin_
No,234,Type:,College,Authors:,,,
Local,config
0,0,0,STRING_d,32
0,0,0,STRING_e,32
0,0,0,STRING_f,32
end,,,,,
#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use feature qw(say);

my $csv= "./file.txt";  

die "cannot open csv\n" if (!open(CSV, "<$csv" ));

my %storage;
my $compiler;
my $macro;



my @bil = qw(
STRING_a
STRING_b
STRING_c
STRING_d
STRING_e
STRING_f
STRING_x
STRING_y
STRING_z
STRING_k
);

while (<CSV>){
    chomp(my $line =$_);
    next if ($line !~ /^No|^\d+/ );
    $compiler = $1 if ($line =~ /No,\d+,Type:,(\w+)/);
        if ($line =~ /\d+,\d+,\d+,(\w+),/){
            $macro=$1;
            push @{$storage{$compiler}},$1;

}


}
close CSV;
print Dumper \%storage;


for my $bil(@bil) {
    while (my ($k,$v) =each%storage ){
        print "Line-----$bil,,,, $v\n";
        if ($bil =~$v){
            #Need help (I want to store the $v into an array having the name $k)
        }
}


}
arrays perl hash
2个回答
0
投票

也许是这样的。它分两个阶段处理文件。

Stage 1 解析输入数据,提取对我们有用的信息并将其存储在哈希中。散列的键是数组名称,散列中的值是包含数组元素的数组引用。

第 2 阶段遍历我们在第 1 阶段构建的内容,并将其转换为所需的输出。

#!/usr/bin/perl

use strict;
use warnings;
use feature 'say';

# Where we're going to store the useful bits of the
# data during the parsing stage
my %data;
# Where we store the name of the current hash key.
my $key;

# Stage 1: Parsing
while (<>) {
  # This looks for the array name record, extracts the
  # string from between "Type" and "Authors" and stores that
  # string as $key
  if (/Type:,(\w+),Authors:/) {
    $key = $1;
  }

  # This looks for "STRING" record, extracts that from the input
  # line and pushes that onto the end of the current array reference
  if (/(STRING[^,]+)/) {
    push @{$data{$key}}, $1;
  }
}

# Stage 2: Output
# For each key in the data hash...
for (keys %data) {
  # ... extract the data we want and print it
  say '@', "$_ = (", join(', ', @{$data{$_}}), ')';
}

0
投票

以下是您的代码的重组版本。

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use feature qw(say);

my $csv= "./file.txt";

open(CSV, "<", $csv )
    or die "cannot open csv\n";

my %storage;
my $compiler;

my %bil = map { $_ => 1}
          qw(
            STRING_a
            STRING_b
            STRING_c
            STRING_d
            STRING_e
            STRING_f
            STRING_x
            STRING_y
            STRING_z
            STRING_k
        );

while (<CSV>){
    chomp(my $line = $_);

    next
        if $line !~ /^No|^\d+/ ;

    $compiler = $1
        if ($line =~ /No,\d+,Type:,(\w+)/);

    if ($line =~ /\d+,\d+,\d+,(\w+),/){
        my $macro = $1;
        push @{ $storage{$compiler} }, $1;
    }
}

close CSV;
# print Dumper \%storage;

my @school     = grep { $bil{$_} } @{ $storage{School}     } ;
my @University = grep { $bil{$_} } @{ $storage{University} } ;
my @College    = grep { $bil{$_} } @{ $storage{College}    } ;

say "school     [@school]";
say "University [@University]";
say "College    [@College]";

运行给出这个输出

school     [STRING_x STRING_y STRING_z STRING_k]
University [STRING_a STRING_b STRING_c]
College    [STRING_d STRING_e STRING_f]

如果

compilers
的完整列表(即学校、大学、学院)仅在
file.txt
中可用,您可以按如下方式修改代码以创建一个
results
哈希来存储每个列表的数据
compilers

#!/usr/bin/perl

use strict;
use warnings;
use Data::Dumper;
use feature qw(say);

my $csv= "./file.txt";

open(CSV, "<", $csv )
    or die "cannot open csv\n";

my %storage;
my $compiler;
my @compilers;

my %bil = map { $_ => 1}
          qw(
            STRING_a
            STRING_b
            STRING_c
            STRING_d
            STRING_e
            STRING_f
            STRING_x
            STRING_y
            STRING_z
            STRING_k
        );

while (<CSV>){
    chomp(my $line = $_);

    next
        if $line !~ /^No|^\d+/ ;

    if ($line =~ /No,\d+,Type:,(\w+)/) {
        $compiler = $1 ;
        push @compilers, $compiler;
    }

    if ($line =~ /\d+,\d+,\d+,(\w+),/){
        my $macro = $1;
        push @{ $storage{$compiler} }, $1;
    }
}

close CSV;

my %results ;

for my $comp (@compilers)
{
    @{ $results{$comp} } = grep { $bil{$_} } @{ $storage{$comp} } ;
}

say Dumper \%results;

输出是

$VAR1 = {
          'University' => [
                            'STRING_a',
                            'STRING_b',
                            'STRING_c'
                          ],
          'School' => [
                        'STRING_x',
                        'STRING_y',
                        'STRING_z',
                        'STRING_k'
                      ],
          'College' => [
                         'STRING_d',
                         'STRING_e',
                         'STRING_f'
                       ]
        };
© www.soinside.com 2019 - 2024. All rights reserved.