2011-07-01 95 views
1

我有這個數據集 - 我只關心類ID,進程@服務器: 我想加載所有三個到多級哈希。填充多級哈希

class_id: 995 (OCAive ) ack_type: NOACK  supercede: NO copy: NO bdcst: NO 
PID         SENDS RECEIVES RETRANSMITS TIMEOUTS MEAN S.D. # 
21881 ([email protected]   )   1   1    0   0 
24519 ([email protected]   )   1   1    0   0 
26163 ([email protected]   )   1   1    0   0 
28069 ([email protected]   )   23   4    0   0 
28144 ([email protected]   )   33   5    0   0 
29931 ([email protected]  )   1   1    0   0 
87331 ([email protected]   )   1   1    0   0 
            ---------- ---------- ---------- ---------- ------- ------- ------ 
              61   14    0   0 

當我嘗試填充散列,它並沒有得到多少(以下數據翻鬥結果)

$VAR1 = ''; 
$VAR2 = { 
    '' => undef 
}; 

這是代碼:

#!/usr/bin/perl -w 
use strict; 
my $newcomm_dir = "/home/casper-compaq/work_perl/newcomm"; 
my $newcomm_file = "newcomm_stat_result.txt"; 

open NEWCOMM , "$new_comm_dir$newcomm_file"; 
while (<NEWCOMM>) { 
    if ($_ =~ /\s+class_id:\s\d+\s+((\w+)\s+)/){ 
     my $message_class = $1; 
    } 
    if ($_ =~ /((\w+)\@\w+\s+)/) { 
     my $process = $1; 
    } 
    if ($_ =~ /(\w+\@(\w+)\s+)/) { 
     my $servers = $1; 
    } 

    my $newcomm_stat_hash{$message_class}{$servers}=$process; 


    use Data::Dumper; 
    print Dumper (%newcomm_stat_hash); 
} 

回答

1

我懷疑你的主要錯誤是,你不打開文件時,由於路徑缺少/,目錄之間和文件名。您可以使用autodie附註檢查打開是否成功,或者您可以使用or die "Can't open file: $!"

您有一些範圍問題。首先,$message_class將在整個循環中未定義,因爲它的範圍僅在一次迭代中持續。如果您希望稍後能夠使用它,您可能還希望在循環外有散列。

我在標題行檢查中輸入next語句,因爲其他檢查在該行中無效。如果你想更精確一點,你可以把整個事情放在循環之外,只需要進行單行檢查。

您不需要兩個變量用於進程和服務器,只需直接使用它們,並且兩者同時使用。

最後,您可能希望在打印中將散列引用發送到Data::Dumper,否則散列將會擴展,並且打印會有些誤導。

#!/usr/bin/perl -w 
use strict; 
use autodie; 
my $newcomm_dir = "/home/casper-compaq/work_perl/newcomm/"; 
my $newcomm_file = "newcomm_stat_result.txt"; 

open my $fh, '<', "$new_comm_dir$newcomm_file"; 

my $message_class; 
my %newcomm_stat_hash; 
while (<$fh>) { 
    if (/^\s+class_id:\s+\d+\s+\((\w+)\)\s+/){ 
     $message_class = $1; 
     next; 
    } 
    if (/(\w+)\@(\w+)/) { 
     $newcomm_stat_hash{$message_class}{$2}=$1; 
    } 
} 
use Data::Dumper; 
print Dumper \%newcomm_stat_hash; 
+0

文件沒有被打開 - 並且變量超出了範圍 - 在腳本的根目錄(開始)對它們進行了範圍填充散列。哈希的更深層節點的合併,我真的很喜歡。從來沒有見過它,它使哈希更可讀。 $ newcomm_stat_hash {$ message_class} {$ 2} = $ 1 – capser

+0

@capser您應該用綠色複選標記標記答案,以表示最佳答案。 – TLP

+1

所有的評論都很有幫助,但是減少一些語句使得代碼更具可讀性。 $ newcomm_stat_hash {$ message_class} {$ 2} = $ 1; – capser

2

你是我裏面的聲明如果只有範圍直到if塊的結尾,並且你的散列分配不應該有我的。嘗試在while循環之前聲明%newcomm_stat_hash,並在while塊的頂部聲明$message_class$process$servers

你也可能想檢查你的失敗打開;我懷疑你錯過了/那裏。

3

除了聲明問題之外,你的regex表達式還有很多問題。我建議在試圖將其插入到散列之前,確保您獲得預期的輸出到每個變量中。

一方面,您需要將括號與\(,\)相匹配,否則它們只會被解釋爲變量容器。

+0

將斜槓添加到目錄的末尾,並在頂部進行聲明 - 謝謝。 – capser

1

您的文件是否正在打開?

我認爲你需要改變:

open NEWCOMM , "$new_comm_dir$newcomm_file"; 

要:

open NEWCOMM , $new_comm_dir.'/'.$newcomm_file; 
+0

是的 - 我應該從現在開始把「或者死掉$ !;」閱讀完文件後。這是如此尷尬。 – capser