我不知道您是否被允许提出有关学校作业的问题。我只是想了解我应该做什么,而不是为我做这件事。也许我错过了一些如此简单的东西,它就在我面前,但无论如何它是基于一个较旧的任务,但我错过了这个课程,我现在遇到了一堵墙,问题是我和我一样。我试图将数组推入哈希表。使用这样的东西;
push @{$hash_table{$hash_key}}, $port
并在存储它们时计算端口,然后打印哈希的内容
while ( ($key , $value) = each ( %hash ) ) {
print “$key scanned @{$value}”
}
如果我想对结果进行排序,我会使用
< foreach $key ( keys ( %hash ) ) {
}
我当前的代码是这样的,搜索/ iNext-DROP /的字符串 使用提供的日志文件。我不能为我的生活找到添加上面代码的正确位置
use warnings;
my $LogRecord;
my $LogRecordCount;
open LOGFILE, "sample.log.txt" or die "couldn't open sample.log.txt";
while ($LogRecord = <LOGFILE>) {
if ($LogRecord =~ /INext-DROP/) {
$LogRecordCount ++;
$LogRecord =~ /(SRC=[0-9\.]* ).*(SPT=[0-9\.]* )/;
$source=$1;
$sport=$2;
print "$source$sport";
print substr( $LogRecord , 0 , $ARGV[1] ) , "\n" if $ARGV[1];
}
}
print "The file contained $LogRecordCount records" if $ARGV[1];
close LOGFILE;
这是带有评论的旧代码的图片; Old Code -- not much has changed since I keep going back after it doesn't work
答案 0 :(得分:3)
你似乎遇到问题的是,你不确定捕获端口的位置和哈希更新。
正在发生的事情是您的while
循环一次迭代文件一行,并将$LogRecord =~
行正在捕获模式的值捕获到$1
和{{1} }。
然后$2
是您可以使用$2
添加到哈希的内容。
然而,有一些事情我改变了风格,比如使用词法文件句柄,因为它的风格更好。
push
这是你的哈希。
但是当谈到输出时:
#!/usr/bin/env perl
use warnings;
use strict;
#because it makes debugging easier.
use Data::Dumper;
my $LogRecordCount;
#declare some hashes;
my %ports_from;
my %ips_that_used;
open my $logfile, "sample.log.txt" or die "couldn't open sample.log.txt";
while (my $line = <$logfile>) {
#matches 'current line' - skips stuff that doesn't match.
next unless $line =~ /INext-DROP/;
#increment count.
$LogRecordCount++;
my ( $source, $src_port ) = $line =~ m/SRC=([0-9\.]+).*SPT=([0-9]+)/;
print "$source$sport";
#not sure what this is doing, so I have left it in.
print substr( $line , 0 , $ARGV[1] ) , "\n" if $ARGV[1];
push @{$ports_from{$source}}, $src_port;
push @{$ips_that_used{$src_port}}, $source;
}
print "The file contained $LogRecordCount records" if $ARGV[1];
close $logfile;
print Dumper \%ports_from;
print Dumper \%ips_that_used;
如果您想对它们进行排序,则必须使用foreach my $ip ( keys %ports_from ) {
print "$ip: ", join ( " ", @{$ports_from{$ip}}) ,"\n"
}
执行此操作。
现在sort
是一个非常聪明的功能,但默认情况下会按字母数字排序。那就是......当涉及到IP地址或端口号时,实际上并不是那么有用,因为你可能想要用数字来对它们进行排序。简单的答案是sort
并使用Sort::Naturally
。
然而 - nsort
接受一个函数(默认为sort
),它根据相对位置返回-1,0,1。
因此,按IP排序可能如下所示:
cmp
然后你可以:
sub by_ip {
my @a = split /\./, $a;
my @b = split /\./, $b;
foreach my $octet ( @a ) {
my $comparison = $octet <=> shift ( @b );
return $comparison if $comparison;
}
return 0;
}
给你:
foreach my $ip ( sort by_ip keys %ports_from ) {
print "$ip: ", join ( " ", sort { $a <=> $b } @{$ports_from{$ip}}),"\n";
}
考虑到存在重复项的IP到端口映射,仅使用散列哈希而不是数组散列来计算端口频率可能更好。
24.64.208.134 : 24128 24128 24128
71.228.199.109 : 37091
72.197.8.56 : 9258
75.117.31.43 : 3122
99.248.20.48 : 48725
207.68.178.56 : 80
然后:
$count_ports_from{$source}{$src_port}++;
给你类似的东西:
foreach my $ip ( sort by_ip keys %count_ports_from ) {
print "$ip: ";
foreach my $port_num ( sort { $count_ports_from{$a} <=> $count_ports_from{$b} }
keys %{ $count_ports_from{$ip} } )
{
print "\t $port_num : $count_ports_from{$ip}{$port_num}\n";
}
}