我正在研究计算机编程最终的介绍,我正在使用Perl进行编码。
我正在尝试使用哈希来过滤IP地址列表,并将所有唯一的地址推送到数组中。
出于某种原因,它只持有两个IP中的一个。
my @broken_data;
my @source_ip;
my @source_ip_mod;
my @destin_ip;
my @destin_ip_mod;
my $file_input;
my $file_output;
my $countline = 0; # set counter to 0
my $countuser = 0;
my $countpass = 0;
# Command to open the source file for use. Gives user the option of what file to look at.
print "Please enter a file name for diagnosis. \n";
$file_input = <STDIN>; # file name input
chomp $file_input;
open SF, $file_input or die "Couldn't open Source File: $!\n"; # open the users file
# allows the user to name the File Output
print "Please enter a file name for the summary output. \n";
$file_output = <STDIN>; # collects name
chomp $file_output; # chomps the input
open(SFO, ">$file_output") or die "Couldn't create $file_output. \n"; # creates a file in current directory for output
while (<SF>) { # while SF is open
$countline++; # counts each line
if ($_ =~ /USER/i) {
$countuser++;
}
if ($_ =~ /PASS/i) {
$countpass++;
}
chomp($_);
if ($_ =~ /^22:28/) { # look for any instence of 22:28, ^ to match with the beginning of string
@broken_data = split(' ', $_); # takes the data and splits it at the space
print "$broken_data[0], $broken_data[2], $broken_data[4], $broken_data[-1]\n"; # takes out each element that i need to work with
print "\tTime: $broken_data[0]\n"; # Prints the time portion of the array
@source_ip = split('\.', $broken_data[2]); # splits the source ip at the period
print "\tSource IP: $source_ip[0].$source_ip[1].$source_ip[2].$source_ip[3] Port: $source_ip[-1]\n"; # Prints the Source IP
@destin_ip = split('\.', $broken_data[4]); # splits the destination ip at the period
@destin_ip_mod = split(':', $destin_ip[4]); # cuts off the trailing semi-colon
$destin_ip[4] = $destin_ip_mod[0];
print "\tDestination IP: $destin_ip[0].$destin_ip[1].$destin_ip[2].$destin_ip[3] Port: $destin_ip[4]\n";
print "\tPacket size: $broken_data[-1].\n";
}
}
my @unique_source_ip; # creates an array for the unique source ips
my %seen_source_ip; # hash to sort the data
foreach $_ (@broken_data[2]) { # foreach loop, setting the Source IP to the default scalar
if (!$seen_source_ip{$_}) { # if the source IP has not been seen, put it into the default scalar
push(@unique_source_ip, $_); # push the default varriable into the unique source ip array
$seen_source_ip{$_} = 1;
}
}
my $unique_source_cnt = @unique_source_ip;
答案 0 :(得分:2)
我能做的最好的事情就是告诉你如何编写相同的代码。我不是说这将是我的解决方案,因为我无法准确理解你在做什么,但我希望你能看到有更好的方法来编写软件。
最大的区别是
use strict
和use warnings
。您应该使用您编写的每个程序执行此操作,无论多小。没有use strict
,用my
声明任何变量是没有意义的,因为Perl只会在任何地方使用包变量。
正确缩进代码,只有在编写非常复杂的内容时才写注释。当您做添加评论时,永远不要说代码正在做什么 - 代码本身就是这样做的。相反,说为什么它正在做它。大多数情况下,您的代码应该是不言自明的。
不要在顶部的块中声明所有变量。你可能也不会像我说的那样费心。这通常是程序员使用C语言的遗产,重要的是要记住Perl和C之间几乎没有任何相似之处。
使用open
和词法文件句柄的三参数形式。在$!
字符串中加入die
的值,以便您知道为什么打开失败。
问题可能在你的原始行
foreach $_ (@broken_data[2]) {
执行循环一次,将$_
设置为$broken_data[2]
的值。每次执行@broken_data
读取循环时都会覆盖数组while
,因此当您点击for
时,您正在查看 last 行中的数据读。我不知道你的意图,但我确信这是不对的。
use strict;
use warnings;
print "Please enter a file name for diagnosis: ";
my $input_fname = <STDIN>;
chomp $input_fname;
open my $in, '<', $input_fname or die "Couldn't open '$input_fname': $!";
print "Please enter a file name for the summary output: ";
my $output_fname = <STDIN>;
chomp $output_fname;
open my $out, '>', $output_fname or die "Couldn't create '$output_fname': $!";
my $n = 0;
my @broken_data;
my ($countuser, $countpass) = (0, 0);
while (<$in>) {
chomp;
++$n;
++$countuser if /USER/i;
++$countpass if /PASS/i;
next unless /^22:28/;
@broken_data = split;
print join(', ', @broken_data[0, 2, 4, -1]), "\n";
print "\tTime: $broken_data[0]\n";
my @source_ip = split /\./, $broken_data[2];
print "\tSource IP: ", join('.', @source_ip[0,1,2,3,-1]), "\n";
my @destin_ip = split /\./, $broken_data[4];
my @destin_ip_mod = split /:/, $destin_ip[4];
$destin_ip[4] = $destin_ip_mod[0];
print "\tDestination IP: ", join('.', @destin_ip[0..4]), "\n";
print "\tPacket size: $broken_data[-1].\n";
}
my @unique_source_ip;
my %seen_source_ip;
for ($broken_data[2]) {
unless ($seen_source_ip{$_}) {
push(@unique_source_ip, $_);
$seen_source_ip{$_} = 1;
}
}
my $unique_source_cnt = @unique_source_ip;