2016-09-01 123 views
2

即時通訊新的Perl(從昨天晚上開始)。 我有一個哈希數組的問題。從Perl中讀取數組的哈希

以下情況: 我有一些來自日誌記錄應用程序的csv文件。日誌文件是每天創建的,並且結構非常糟糕。我想將它們組合在一起並顯示一些統計數據。 讀取和解析csv並不是一個真正的問題,但我想將這些列存儲在一個散列中以便easyer訪問。 在csv文件中,secound列(PhysName)是我想要對其分組數據的列。所以我認爲,最好只保存散列內的其他列,將數個散列保存在一個數組中,並將數組保存在另一個散列中,我將PhysName作爲Key。

這是不是一個大問題,在所有:

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); 
    } 
} 

當我試着使用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' 
      } 
     ]; 

我首先想到的是,該自卸車顯示我奇數$ VAR作爲關鍵字,甚至$ VAR作爲Values,但是當我仔細觀察偶數$ VAR中的哈希值後,我非常舒服我在插入內部哈希值的時候做了一些錯誤(列和值)存儲到數組中,存儲在%dauerauftraege哈希中。

所以,現在當它來自哈希閱讀,包含哈希數組這個代碼在這裏

# 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"); 
    } 
} 

我總是得到這個錯誤:

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 

這讓我相信的時候,我的問題是在followinig線:

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

當我仔細閱讀這一行,我明白第e如下: $dauerauftraege{"$phys_name"}返回給我一個包含對該數組的引用的標量($),該數組通過@{}解除引用到Array。 現在與\%values我通過參考values哈希到push Funktion,它將它添加到數組的引用,這是由@前面的\指示的。

我會很高興,如果有人能幫助我解決這個問題。 非常感謝你們:-)

+0

傳遞一個哈希引用自卸車,然後張貼的輸出,而不是:'打印(自卸車( \%dauerauftraege))' – toolic

+0

https://gist.github.com/anonymous/8750158b1d3a7f5d840b35c24bd4c16a 對不起,這個小盒子在這裏的輸出太長:) :) 但它看起來像我一樣,我已經postet上面我的問題。 – C3D1

+1

'foreach my $ dauerauftrag_values(@dauerauftrag)'''print(%{$ dauerauftra_values} {'date_time'});'變量的名稱不相同! '$ dauerauftrag_values'不是'$ dauerauftra_values' – Mike

回答

1

我認爲這個問題是您如何訪問你的數據結構。試試這個:

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"; 
    } 
} 
+0

這真的很適合我,就像一個魅力。感謝你的代碼,我現在看到,我犯了錯誤。保護你! :-) – C3D1

1

看起來好像你不太明白如何解引用數據結構。看看下面的代碼,我一直在希望改變了一點也許會讓事情更清楚一點:

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"; 
} 

perldsc

+0

是的,你說得對。我在解引用時遇到了一些問題。 – C3D1

1

始終使用編譯use strict;use warnings;。他們幫助避免錯別字和其他問題。

%dauerauftraege是一個散列,你試圖像數組一樣訪問它。並且您正試圖在散列中進行循環,並且同時在整個散列的每次迭代中進行打印。

我認爲代碼可能是這個樣子:

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'}[email protected]_data[0,2..6]; 
    } 
} 

並打印...

# 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"; 
} 
+1

請使用詞法文件句柄。 – simbabque

+0

非常感謝您的回答。 +1因爲我喜歡,你是怎麼用Perl完成「單行如果」的。像這樣真的,讓代碼看起來像上帝:-) +1也暗示'use strict;'和'use warnings;'! :) – C3D1