2012-02-29 50 views
1

我有一所學校計劃我剛剛得到的陣列,我們正在學習散列和老師走了過去陣列的哈希值,但沒有真正陣列哈希我覺得自己像一個AOH是要對我的工作進行更好從長遠來看。現在,我將所有數據都存入單獨的變量,並且我希望將它們存儲到AoH bc中。我的整個時間都有相同的變量,但值會更改。將數據存儲到哈希

什麼程序,是一個日誌分析器,並通過一個巨大的日誌文件分析和所有的數據是,是,是這樣的線路。

IPADDY x x [DATE:TIME -x] "METHOD URL HTTPVERS" STATUSCODE BYTES "REFERER" "USERAGENT" 

例如線是

27.112.105.20 - - [09/Oct/2011:07:22:51 -0500] "GET/HTTP/1.1" 200 4886 "-" "Python-urllib/2.4" 

現在我得到的所有數據精我只是不真正瞭解如何填充和散列的數組如果有人能幫助我。

這裏是一個更新的代碼,抓取數據並嘗試將其存儲到AoH中。我的文件中的輸出曾經是完美的,就像我現在評論的打印語句一樣。這就是我的輸出文件現在的所有「ARRAY(0x2395df0):HASH(0x23d06e8)」。難道我做錯了什麼?

#!/usr/bin/perl 
use strict; 
use warnings; 

my $j = 0; 
my @arrofhash; 
my $ipadd; 
my $date; 
my $time; 
my $method; 
my $url; 
my $httpvers; 
my $statuscode; 
my $bytes; 
my $referer; 
my $useragent; 
my $dateANDtime; 
my ($dummy1, $dummy2, $dummy3); 

open (MYFILE, '>>dodoherty.report'); 

if (@ARGV < 1) 
{ 
     printf "\n\tUsage: $0 file word(s)\n\n"; 
     exit 0; 
} 

for (my $i = 0; $i < @ARGV; ++$i) 
{ 
    open(HANDLE, $ARGV[$i]); 
    while(my $line = <HANDLE>) 
    { 

      ($ipadd, $dummy1, $dummy2, $dateANDtime, $dummy3, $method, $url, $httpvers, $statuscode, $bytes, $referer, $useragent) = split(/\s/, $line); 
      $method = substr ($method, 1, length($method)); 
      $httpvers = substr ($httpvers, 0, length($httpvers)-1); 
      $referer = substr ($referer, 1, length($referer)-2); 
      $useragent = substr ($useragent, 1, length($useragent)-1); 
      if (substr ($useragent, length($useragent)-1, length($useragent)) eq '"') 
      { 
        chop $useragent; 
      } 
      if ($dateANDtime =~ /\[(\S*)\:(\d{2}\:\d{2}\:\d{2})/) 
      { 
        $date = $1; 
        $time = $2; 
      } 

      $arrofhash[$i] = {ipadd => $ipadd, date => $date, 'time' => $time, method => $method, url => $url, httpvers => $httpvers, statuscode => $statuscode, bytes => $bytes, referer => $referer, useragent => $useragent}; 

#    print MYFILE "IPADDY :$ipadd\n"; 
#    print MYFILE "METHOD :$method\n"; 
#    print MYFILE "URL :$url\n"; 
#    print MYFILE "HTTPOVERS : $httpvers\n"; 
#    print MYFILE "STATUS CODE: $statuscode\n"; 
#    print MYFILE "BYTES : $bytes\n"; 
#    print MYFILE "REFERER : $referer\n"; 
#    print MYFILE "USERAGENT : $useragent\n"; 
#    print MYFILE "DATE : $date\n"; 
#    print MYFILE "TIME : $time\n\n"; 

    } 
} 

for (my $j = 0; $j < @arrofhash; ++$j) 
{ 
    foreach my $hash (@hashkeys) 
    { 
      printf MYFILE "%s: %s\n",$hash, $arrofhash[$j]; 
    } 
    print MYFILE "\n"; 
} 


close (MYFILE); 

回答

1

一個常見的初學者的錯誤是沒有使用的變量的詞法範圍的,只是在頂部聲明所有變量,像你一樣。在你需要的範圍內聲明它們,不多也不少。

在你的情況下,也將是有益的只是直接存儲中的數據的散列,然後推該散列參照的數組。我還建議不要在這裏使用split,因爲它的工作不可靠,而且你正在拆分引用的字符串,使用虛擬變量來擺脫不需要的數據。而是使用正則表達式。

此正則表達式不會處理逃脫,引號裏的報價,但我得到的是你不會有處理這種感覺,因爲你正在使用前分裂處理這個問題。

您將需要添加任何進一步處理的數據,如提取日期和時間等,如果你想要一些額外的安全性,你可以添加一個警告,如果正則表達式似乎已經失敗,例如unless (%f) { warn "Warning: Regex did not match line: '$_'"; next; }

use strict; 
use warnings; 
use Data::Dumper; 

my @all; 
while (<DATA>) { 
    my %f;     # make a new hash for each line 
          # assign the regex captures to a hash slice 
    @f{qw(ipadd dateANDtime method statuscode bytes referer useragent)} = 
     /^     # at beginning of line... 
      (\S+) [\s-]* # capture non-whitespace and ignore whitespace/dash 
      \[([^]]+)\]\s* # capture what's inside brackets 
      "([^"]+)"\s* # capture what's inside quotes 
      (\d+)\s*  # capture digits 
      (\d+)\s* 
      "([^"]+)"\s* 
      "([^"]+)"\s* 
     $/x;    # ..until end of line, /x for regex readability only 
    push @all, \%f;  # store hash in array 
} 

@f{qw(date time)} = split /:/, $f{dateANDtime}, 2; 
print Dumper \@all;  # show the structure you've captured 

__DATA__ 
27.112.105.20 - - [09/Oct/2011:07:22:51 -0500] "GET/HTTP/1.1" 200 4886 "-" "Python-urllib/2.4" 
+0

哇這看起來更清潔我的唯一想法是我應該有日期和時間作爲單獨的變量,但我相信我可以修復這個正則表達式一點點。 – Trance339 2012-02-29 17:05:42

+1

@ Trance339我建議你事後做處理。例如。 'my($ date,$ time)= split /:/,$ f {dateANDtime},2;'2「是分割的LIMIT參數,它決定了要返回多少個字段。 – TLP 2012-02-29 17:29:12

1

基本上你只需要聲明的頂層結構,然後用它:

my @AoH; 

$AoH[0]{some_key} = 5; 
$AoH[1]{some_other_key} = 10; 
# ^^ second level is a hash 
# | first level is an array 

這將創建兩個元素,每個哈希值,每一個鍵的數組。此功能稱爲autovivification,它使容器結構在使用時彈出。

所有這些都記錄在perldsc教程中。

在你的情況,這將是這樣的:

$arrofhash[$i]{key_name} = value; 
$arrofhash[$i]{another_key} = another_value; 
... 

$arrofhash[$i] = {key => value, key2 => value2, ...} 

在一次集全散。

+0

我想我會在我的陳述中嘗試整套,看看我需要哪裏。看起來我可以做一些像...... $ arrofhash [$ i] = {ipadd => $ ipadd,date => $ date,time => $ time ...} 等等之類的東西,所以每次鍵是相同的,但是值是不同。 – Trance339 2012-02-29 16:06:32