2013-12-10 36 views
-2

任何人都可以告訴我爲什麼其他所有的東西都可以工作,除了我的USER和PASS計數器變量在我'while'循環的底部?當他們輸出3個用戶和2個輸入時,將它們重置爲零。爲什麼我的變量重置爲零 - perl

(代碼是計算有多少實例是Word用戶,並通過了路上經過。)

如果你看到任何其他的馬虎錯誤,請讓我知道!謝謝!

輸入文件的第一行(注:這種格式將重複2006年的線條,只是數字的變化)

22:28:31.819551 IP 98.114.205.102.1924 > 192.150.11.111.1957: Flags [P.], seq 1:124, ack 2, win 64239, length 123E...<[email protected]\.bfP....Y..echo USER 1 get ssms.exe 

代碼:

use strict; 
use warnings; 
use diagnostics; 

open MYFILE, '<', 'source_file.txt' or die $!; 
open OUT, '>', 'Summary_Report.txt' or die $!; 
open OUTFILE, '>', 'Header.txt' or die $!; 

my $start_time = undef; 
my $end_time; 
my $user = 0; 
my $pass = 0; 
my $linenum = 0; 

while (<MYFILE>) {    # loops through every line in file 
    chomp;      # break new line 
    $linenum++;     # count line 1 to end of file, 2006 
    if (/^\d+:\d+/) { 
     my @header = split (/\s+/, $_); 
     print OUTFILE "$linenum: @header\n\n"; 
     if (/^22:28/ && !defined($start_time)) { 
      $start_time = $header[0]; 
     } 
     if (/22:28/) { 
      $end_time = $header[0]; 
     } 
     $user++ if /USER/ig; 
     $pass++ if /PASS/ig; 
    } 
} 

print OUT "Total # of times phrases were used:\n\n 
    USER (variations thereof) = $user\n\n 
    PASS (variations thereof) = $pass\n\n\n"; 

好大家好,這裏是每一個我的代碼的最後一位。 (輸出都還沒有完成,這就是爲什麼有些人仍然沒有答案,但你可以得到什麼,我工作的一個想法,需要做什麼。

#!/usr/bin/perl -w 

# Final project 
use strict; 
use warnings; 
use diagnostics; 

#opens txt file: read mode 
open MYFILE, '<', 'source_file.txt' or die $!; 

#opens output txt file: write mode 
open OUT, '>', 'Summary_Report.txt' or die $!; 

#open output txt file: write mode 
#used to store header 'split' info 
open OUTFILE, '>', 'Header.txt' or die $!; 

my $i = 0; 
$| = 1; #disable output buffering 

my $start_time = undef; #undefined to avoid recycling through other time stamps 
my $end_time; 

my $user = 0; 
my $pass = 0; 

my $packet_size = 0; #goes with length# 

my @header; 

my @source_ip; 
my @source_port; 
my $src_port; 
my @src_port; 

my @dest_ip; 
my @dest_port; 
my $destination_port; 
my @destination_port; 


while (<MYFILE>) { #loops through every line in file 
    chomp; #break new line 

    if (/^\d+:\d+/) { 

    #separate pieces of information from TCPDUMP into list 
    @header = split (/\s+/, $_); 
    print OUTFILE "$.: @header\n\n"; 

##############################T I M E################################## 

    #defining first 'line & time' as 'special' 
    if (/^22:28/ && !defined($start_time)) { 
     $start_time = $header[0]; 
     #print "$start_time\n"; ###used as a check### 
    } 

    #Used recycling of time stamps to find last one available 
    if (/22:28/) { 
     $end_time = $header[0]; 
    }  

#############################S O U R C E################################# 

    #categorizing each section of ip's from source 
    @source_ip = split ('\.', $header[2]); 

    #adding ip's together, joining in concatenation by '.' 
    $source_ip[$i] = $source_ip[0] . '.' . $source_ip[1] . '.' . $source_ip[2] . '.' .  $source_ip[3]; 
    #print $source_ip[$i]; (check) 

    @source_port = split (':', $source_ip[4]); 
    $src_port[$i] = $source_port[0]; 

#########################D E S T I N A T I O N########################### 

    #categorizing each section of ip's from destination 
    @dest_ip = split ('\.', $header[4]); 

    #adding ip's together, joining in concatenation by '.' 
    $dest_ip[$i] = $dest_ip[0] . '.' . $dest_ip[1] . '.' . $dest_ip[2] . '.' . $dest_ip[3]; 
    #print $dest_ip[$i]; (check) 

    @dest_port = split (':', $source_ip[4]); 
    $destination_port[$i] = $dest_port[0]; 

#############################L E N G T H################################# 

    #-1 represents length 
    $packet_size = $packet_size + $header[-1]; 
    #print $packet_size; (check) 

    $i++ 
    } 
} 

close MYFILE; 

#########################D A T A S E C T I O N########################### 

open MYFILE, '<', 'source_file.txt' or die $!; 

#I am separating loop to reset values# 
while (<MYFILE>) { 

    #finds all instances of USER 
    $user++ if /USER/ig; 
    #print "user" (use as check) 

    #finds all instances of PASS 
    $pass++ if /PASS/ig; 
    #print "pass" (use as check) 

} 

#Output summary to new file: overwrite file 
print OUT "SUMMARY REPORT:\n\n"; 

print OUT "# of total lines in the file = $.\n\n\n"; 

print OUT "Range of time the file encompasses:\n\n 
    Starting Time = $start_time\n\n 
    Ending Time = $end_time\n\n 
    Total Time = 16.219218\n\n\n"; 

print OUT "Total # of distinct SOURCE ip addresses = \n\n\n"; 

print OUT "Total # of distinct DESTINATION ip addresses = \n\n\n"; 

print OUT "Listing of distinct SOURCE ip addresses = \n\n\n"; 

print OUT "Listing of distinct DESTINATION ip addresses = \n\n\n"; 

print OUT "Total # of distinct SOURCE TCP ports = \n\n\n"; 

print OUT "Total # of distinct DESTINATION TCP ports = \n\n\n"; 

print OUT "Listing of distinct SOURCE TCP ports = \n\n\n"; 

print OUT "Listing of distinct DESTINATION TCP ports = \n\n\n"; 

print OUT "Total # of times phrases were used:\n\n 
    USER (variations thereof) = $user\n\n 
    PASS (variations thereof) = $pass\n\n\n"; 

print OUT "DETAIL SECTION:\n\n\n"; 

print OUT "SOURCE IP address activity by port over time:\n\n 
    Mean packet size for above = \n\n 
    Median packet size for above = \n\n\n"; 

print OUT "Detail IP address activity by port over time:\n\n 
    Mean packet size for above = \n\n 
    Median packet size for above = \n\n\n"; 

print OUT "Any and all interesting text w/in the DATA section of the file:\n\n"; 
close OUT;    # 
close OUTFILE;   #close remaining files 
close MYFILE;   # 
+0

你能告訴我們'source_file.txt'的內容嗎? – jwodder

+1

我不認爲它是遞增的。將最後一個打印語句移動到'pass ++'下的'while ... if..'中,以便打印每個循環迭代的值。 – slebetman

+3

'$ linenum'也被稱爲內置'$ .' – TLP

回答

2

短短几年的觀察,也許這將求助:

讓我們來看看你的循環:

while (<MYFILE>) {         # 1 
    chomp;           # 2 
    if (/^\d+:\d+/) {        # 3 
     my @header = split (/\s+/, $_);   # 4 
     print OUTFILE "$linenum: @header\n\n";  # 5 
     if (/^22:28/ && !defined($start_time)) { # 6 
      $start_time = $header[0];    # 7 
     } 
     if (/22:28/) {        # 8 
      $end_time = $header[0];    # 9 
     } 
     $user++ if /USER/ig;      # 10 
     $pass++ if /PASS/ig;      # 11 
    } 
} 

你意識到$user++$pass++是if語句內(3號線),它看起來像它應該工作,因爲所有線路的匹配規則EXPRES錫永。 5號線打印出Header.txt。你在Header.txt中獲得任何輸出嗎?如果沒有,您的if在第3行的聲明出現問題。

如果您在Header.txt獲得輸出,我們可以使用grepwc計算的時候,我們得到USERPASS數量:

$ grep /USER/i Header.txt | wc -l # The total you should get for $user 
$ grep /PASS/i Header.txt | wc -l # The total you should get for $pass 

如果這些均爲零,我們知道你是不是發現行數將增加$user$pass

我注意到的另一件事是,你在所有地方使用默認變量$_。這可能會導致問題,因爲$_的值可能會被替換。我沒有看到任何東西,但有可能當你到達#10和#11行時,$_未設置爲你讀入的行。

你應該幾乎總是使用詞法作用域局部變量 - 尤其是包含的不僅僅是幾行代碼迴路:

while (my $line = <MYFILE>) { 
    chomp $line; 
    if ($line =~ /^\d=:\d+/) { 
    .... 
    if ($line =~ /USER/i) { 
     $user += 1; 
    } 
    if ($line =~ /PASS/i) { 
     $pass += 1; 
    } 
} 

這本身就可以解決您的問題 - 特別是如果你縮短你的循環後,你以爲是什麼的相關信息。其他評論者嘗試過你的單行輸入並報告你的代碼適合他們。這可能是因爲你可能在做一些改變$_的值,並沒有把它放在你的編碼樣本中。

請注意,我使用的是固定的if而不是固定的if。它使代碼更清晰一些,因爲有人掃描你的代碼可能會錯過固定的if. Also, it makes it clearer that a single line may be counted twice if they both contain USER and PASS`。這是可能發生的事情嗎?

第6行至第9行對我來說似乎有點不可思議。如果開始時間不是下午10點28分?爲什麼$start_time$end_time似乎都在看同一件事?有沒有事情發生在結束時間,因爲我注意到#8號線沒有Line#6所具有的起始點錨點。

爲什麼不簡單地在第一行讀入$start_time,並在$end_time中讀取最後一行?

此外,你做一個split,但你似乎沒有做任何與數據(除了第一部分)。它也許更有效的做一個substr拉過你想要的數據:

my $time_stamp = substr($line, 0, 15); 

這樣一來,很明顯你只是想的時間印記行的第一部分,你不關心其他的線。查看您的代碼的用戶並不想知道您打算如何處理這些數據。另外,你可以使用一個很好的有意義的名字。啊!,這是一個$time_stamp而不是一些沒有意義的$header[0]。此外,在substr,你可以從22:28:31.819551修剪下來的價值,只是22:28:31

my $time_stamp = substr($line, 0, 8); 

同樣,我看不出有什麼不妥。我試着根據你的代碼生成一堆數據,並通過你的代碼運行它們,但是你似乎有什麼工作。那個循環比你發佈的時間長嗎?


附錄

有幾件事情。您正在使用my在程序的一開始定義變量,就好像您使用COBOL或Pascal編寫的一樣。 my的優點是允許變量作用域。用my定義的變量在詞彙範圍內。也就是說,它只存在於其創建的塊中。這可以幫助您發現錯誤。

不要在程序的開頭定義所有變量。定義它們以利用範圍機制。例如,我們拿@header。這隻用於你的循環。將其定義有:

while (my $line = <MYFILE>) { # Don't use `$_`. Use a real variable! 
chomp $line; #break new line 
my @header = split /\s+/, $line; # Define @header here! 

if ($line =~ /^\d+:\d+/) { 
    print OUTFILE "$.: $line\n\n"; # {rint $line instead of gluing @header back together 

每次經過循環,@header將成爲不確定的一次。純粹和乾淨的下一行你解析。這樣,您不必擔心@header以前的值會妨礙您的工作。

此外,你的循環現在已經足夠長,$_可能會讓你陷入困境。使用一個現實生活中的變量,這個變量的詞彙範圍很大(就像我對$line所做的那樣,很明顯$line包含了什麼),$_可能不是很明顯 - 甚至對你來說也是如此。

此外,看一看這一行:

@dest_ip = split ('\.', $header[4]); 
$dest_ip[$i] = $dest_ip[0] . '.' . $dest_ip[1] . '.' . $dest_ip[2] . '.' . $dest_ip[3]; 

如果我正確地讀它,你有一個變量$i,你遞增,這是怎麼回事每行你解析。但是,您每次都會覆蓋@dest_ip

你爲什麼要這麼做?你想做什麼?您將IP拆分爲四個組,然後將它們放回$dest_ip[$line_number],然後用您的拆分銷燬@dest_ip

你應該看看使用Perl模塊,因爲你真的要解析你的Apache httpd日誌(我相信這是一個Apache httpd日誌)。看一看Apache::LogRegex,看看它是否可以解除您爲獲取所需數據而進行的大量解析。

+0

我作爲答案發布了我的完整代碼,我發佈的內容迄今爲止沒有任何錯誤。 – user2288

+0

@ user2288查看我的附錄。 –

+0

看到我的完整代碼,你認爲我應該讓你的改變仍然存在嗎?這一切都起作用,所以我很緊張,搞砸了。 – user2288

相關問題