有人能告诉我为什么其他一切都有效,除了我的USER和PASS计数器变量在我''while'循环的底部?当他们为用户输出3和为传递输出2时,某些东西会将它们重置为零。
(代码是计算USER和PASS一词的实例数。)
如果您发现任何其他草率错误,请告诉我们!提前谢谢!!
输入文件的第一行(注意:此格式重复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...<.@.q...br.f...o....\.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 :(得分: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行)中。它看起来应该可以工作,因为所有的行都匹配正则表达式。第5行打印到Header.txt
。你在Header.txt
得到任何输出吗?如果没有,您在第3行的if
声明中出现了问题。
如果您要在Header.txt
中获得输出,我们可以使用grep
和wc
来计算我们获得USER
和PASS
的次数:< / p>
$ 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行没有第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
包含的内容很明显。$_
可能并不总是很明显 - 甚至对你来说也是如此。< / p>
另外,请看一下这一行:
@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,看看它是否可以减轻你为获得所需数据所做的大部分解析。