简体   繁体   English

从Perl中的数组读取哈希

[英]Read Hashes from Array in Perl

im new to perl (started yesterday evening). 我是perl的新手(昨天晚上开始)。 I have a problem with array of hashes. 我对哈希数组有问题。

Following situation: I have several csv-files from a logging application. 以下情况:我有一个日志记录应用程序中的多个csv文件。 The logfiles are created daily and are really bad structured. 日志文件是每天创建的,实际上结构不好。 I want to group them together and show some statistics. 我想将它们分组在一起并显示一些统计数据。 Reading and parsing the csv isn't really a problem, but i want to store the columns inside a hash for easyer access. 读取和解析csv并不是一个真正的问题,但我想将列存储在哈希中以便于访问。 Inside the csv-file, the secound column (PhysName) is the column, on which i want to group the data. 在csv文件中,secound列(PhysName)是要在其上对数据进行分组的列。 So i thought, it's a good idea to save only the other columns inside a hash, save several of these hashes inside an array and save the array inside an other hash, where i take the PhysName as Key. 所以我认为,最好只将其他列保存在哈希中,将其中一些哈希保存在数组中,然后将数组保存在另一个哈希中,在这里我将PhysName作为键。

That wasn't a big deal at all: 根本没什么大不了的:

my %dauerauftraege;

# Glob all CSV-Files in folder
my @files = glob("*.csv");

foreach my $file(@files) {
    # read the file
    open(DATA, "<$file") or die("Could not open File");

    LINE:
    foreach my $line(<DATA>) {
        chomp($line);
        if ($line eq "") {
            next LINE;
        }

        # Split Line into Fields
        my @line_data = split(";", $line);

        my $phys_name = $line_data[1];

        # skip the header file
        if ($phys_name eq "PhysName") {
            next LINE;
        }

        my %values =(
        'date_time' => $line_data[0],
        'sender' => $line_data[2],
        'recipient' => $line_data[3],
        'format' => $line_data[4],
        'transport' => $line_data[5],
        'partnername' => $line_data[6]);

        push(\@{$dauerauftraege{"$phys_name"}}, \%values);
    }
}

When i try to verify this with print(Dumper(%dauerauftraege)) i get the following: 当我尝试使用print(Dumper(%dauerauftraege))进行验证时,我得到以下信息:

$VAR1 = 'YYYYYYYXXXXXXXX';
$VAR2 = [
          {
            'transport' => 'FTP',
            'format' => 'V1',
            'partnername' => 'A_TEST',
            'date_time' => '2016.07.25 11:16:52',
            'sender' => 'BBB',
            'recipient' => 'CCC'
          },
          {
            'recipient' => 'CCC',
            'sender' => 'BBB',
            'partnername' => 'A_TEST',
            'date_time' => '2016.07.25 11:17:15',
            'format' => 'V1',
            'transport' => 'FTP'
          }
        ];
$VAR3 = 'XXXXXXXYYYYYYYY';
$VAR4 = [
          {
            'format' => 'V2',
            'partnername' => 'S_TEST',
            'date_time' => '2016.07.25 10:15:02',
            'recipient' => 'DDD',
            'sender' => 'AAA',
            'transport' => 'HTTP'
          },
          {
            'transport' => 'HTTP',
            'recipient' => 'DDD',
            'sender' => 'AAA',
            'partnername' => 'S_TEST',
            'format' => 'V2',
            'date_time' => '2016.07.25 10:15:30'
          }
        ];

My first thought was, that Dumper Displays me the odd $VAR's as keys, and the even $VAR's as Values, but after i take a closer look at the hash inside the even $VAR's, i'm pretty shure i have done something wrong while inserting the inner hash (with the columns and values) into the array, stored in the %dauerauftraege Hash. 我的第一个想法是,Dumper将奇数的$ VAR显示为键,将偶数的$ VAR显示为值,但是当我仔细查看偶数的$ VAR内的哈希后,我很确定我做错了什么同时将内部哈希(带有列和值)插入存储在%dauerauftraege哈希中的数组中。

So, now when it comes to read from the Hash, containing an array of hashes with this code here 因此,现在从散列中读取数据时,在此处包含带有此代码的哈希数组

# Get the keys to iterate over them
my @dauerauftraege_keys = keys(%dauerauftraege);
print("count dauerauftraege: ".(scalar @dauerauftraege_keys)."\n");
# iterate over the keys to get the array of hashes
foreach my $dauerauftrag_key (@dauerauftraege_keys) {
    # retrive the array
    my @dauerauftrag = $dauerauftraege{"$dauerauftrag_key"};
    print("count hashes inside the array: ".(scalar @dauerauftrag)."\n");
    # iterate over the hashes and print the values
    foreach my $dauerauftrag_values (@dauerauftrag) {
        print(%{$dauerauftra_values}{'date_time'});
        print("\n");
        print(%{$dauerauftra_values}{'sender'});
        print("\n");
        print(%{$dauerauftra_values}{'recipient'});
        print("\n");
        print(%{$dauerauftra_values}{'format'});
        print("\n");
        print(%{$dauerauftra_values}{'transport'});
        print("\n");
        print(%{$dauerauftra_values}{'partnername'});
        print("\n");
    }
}

i always get this error: 我总是得到这个错误:

count dauerauftraege: 2
count hashes inside the array: 1
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 56, <DATA> line 5.
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 57, <DATA> line 5.
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 58, <DATA> line 5.
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 59, <DATA> line 5.
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 60, <DATA> line 5.
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 61, <DATA> line 5.
date_timesenderrecipientformattransportpartnernamecount hashes inside the array: 1
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 56, <DATA> line 5.
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 57, <DATA> line 5.
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 58, <DATA> line 5.
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 59, <DATA> line 5.
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 60, <DATA> line 5.
Use of uninitialized value in print at ./LastRun_Evaluation.pl line 61, <DATA> line 5.
date_timesenderrecipientformattransportpartnername

That makes me belive, that my problem is in the followinig line: 这使我相信,我的问题在以下行中:

push(\@{$dauerauftraege{"$phys_name"}}, \%values);

When i carefully read this line, i understand the following: $dauerauftraege{"$phys_name"} returns me a skalar ( $ ) containing an reference to the array, which is dereferenced by @{} to the Array. 当我仔细阅读此行时,我了解以下内容: $dauerauftraege{"$phys_name"}我返回一个skalar( $ ),其中包含对该数组的引用,该引用由@{}取消了对该数组的引用。 And now with \\%values i pass an reference to the values Hash to the push Funktion, which add it to the reference to the array, which is indicated by the \\ in front of the @. 现在,使用\\%values我将对values Hash的引用传递给push ,将其添加到对数组的引用中,该引用由@前面的\\表示。

I would be verry happy, if anyone could help me with this problem. 如果有人可以帮助我解决这个问题,我将非常高兴。 Thank you alot guys :-) 谢谢很多人:-)

It appears as though you don't quite understand how to dereference the data structure. 似乎您不太了解如何取消引用数据结构。 Have a look at the following code which I've changed up a bit in hopes that'll make things a bit clearer: 看看下面的代码,我对它们进行了一些修改,以期使事情变得更加清晰:

my @keys = keys(%dauerauftraege);

for my $key (@keys) {

    print "*** $key ***\n";

    my $aref = $dauerauftraege{$key};

    for my $values_href (@$aref){
        print "$values_href->{date_time}\n";
        print "$values_href->{sender}\n";
        print "$values_href->{recipient}\n";
        print "$values_href->{format}\n";
        print "$values_href->{transport}\n";
        print "$values_href->{partnername}\n";
    }
    print "\n";
}

See perldsc perldsc

I think the problem is how you access your data structure. 我认为问题在于您如何访问数据结构。 Try this: 尝试这个:

my @dauerauftraege_keys = keys %dauerauftraege;
print("count dauerauftraege: ".(scalar @dauerauftraege_keys)."\n");
# iterate over the keys to get the array of hashes
foreach my $dauerauftrag_key (@dauerauftraege_keys) {
    # retrieve the array
    my $dauerauftrag = $dauerauftraege{"$dauerauftrag_key"}; # ref to array
    my @a = @$dauerauftrag;
    print("count hashes inside the array: ".(scalar @a)."\n");
    # iterate over the hashes and print the values
    foreach my $dauerauftrag_values (@a) { # also a reference
        print $dauerauftrag_values->{'date_time'} . "\n";
        print $dauerauftrag_values->{'sender'} . "\n";
        print $dauerauftrag_values->{'recipient'} . "\n";
        print $dauerauftrag_values->{'format'} . "\n";
        print $dauerauftrag_values->{'transport'} . "\n"; 
        print $dauerauftrag_values->{'partnername'} . "\n";
    }
}

Always use pragma use strict; 始终use strict; and use warnings; use warnings; . They help avoid typos and other problems. 它们有助于避免错别字和其他问题。

%dauerauftraege is a hash, you have tried to access it like an array. %dauerauftraege是一个哈希,您试图像数组一样访问它。 And you're trying to make a loop through the hash, and at the same time to print on each iteration of the entire hash. 您正在尝试遍历哈希,同时在整个哈希的每次迭代中进行打印。

I think the code might look something like this: 我认为代码可能看起来像这样:

use strict;
use warnings;
my %dauerauftraege;

# Glob all CSV-Files in folder
my @files = glob("*.csv");

foreach my $file(@files) {
    # read the file
    open(my $fh, "<", $file) or die("Could not open File");

    LINE:
    foreach my $line(<$fh>) {
        chomp($line);
        next LINE unless($line);

        # Split Line into Fields
        my @line_data = split(";", $line);

        my $phys_name = $line_data[1];

        # skip the header file
        next LINE if ($phys_name eq "PhysName");

        @{$dauerauftraege{"$phys_name"}}
          {'date_time', 'sender', 'recipient',
           'format', 'transport', 'partnername'}=@line_data[0,2..6];
    }
}

And print ... 并打印...

# Get the keys to iterate over them
my @dauerauftraege_keys = keys(%dauerauftraege);
print("count dauerauftraege: ".(scalar @dauerauftraege_keys)."\n");
# iterate over the keys to get the array of hashes
foreach my $dauerauftrag_key (@dauerauftraege_keys) {
    print "\n$dauerauftrag_key:\n";
    print join("\n",
          @{$dauerauftraege{"$dauerauftrag_key"}}{'date_time','sender','recipient',
                          'format','transport','partnername'})."\n";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM