Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 在Perl中,如何将数组作为值存储在散列中?_Regex_Perl_Hashtable - Fatal编程技术网

Regex 在Perl中,如何将数组作为值存储在散列中?

Regex 在Perl中,如何将数组作为值存储在散列中?,regex,perl,hashtable,Regex,Perl,Hashtable,我不知道你是否可以问关于学校作业的问题。我只是想知道我应该做什么,而不是为我做这件事。也许我错过了一些非常简单的东西,它就在我面前,但无论如何,它是基于一个较旧的作业,但我错过了这门课,我现在遇到了一堵墙,问题是我试图将数组推到哈希表中。使用类似这样的东西 push @{$hash_table{$hash_key}}, $port 以及在存储端口时对端口进行计数,然后打印哈希的内容 while ( ($key , $value) = each ( %hash ) ) { print “

我不知道你是否可以问关于学校作业的问题。我只是想知道我应该做什么,而不是为我做这件事。也许我错过了一些非常简单的东西,它就在我面前,但无论如何,它是基于一个较旧的作业,但我错过了这门课,我现在遇到了一堵墙,问题是我试图将数组推到哈希表中。使用类似这样的东西

push @{$hash_table{$hash_key}}, $port
以及在存储端口时对端口进行计数,然后打印哈希的内容

while ( ($key , $value) = each ( %hash ) ) {
    print “$key scanned @{$value}” 
}
如果我想对结果进行排序,我会使用

< foreach $key ( keys ( %hash ) ) {
}
我当前的代码是这样的,搜索/inxt-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;
使用警告;
我的$LogRecord;
我的$LogRecordCount;
打开日志文件“sample.log.txt”或die“无法打开sample.log.txt”;
而($LogRecord=){
如果($LogRecord=~/inxt DROP/){
$LogRecordCount++;
$LogRecord=~/(SRC=[0-9\.]*)。*(SPT=[0-9\.]*)/;
$source=$1;
$sport=$2;
打印“$source$sport”;
打印substr($LogRecord,0,$ARGV[1]),“\n”如果$ARGV[1];
}
}
如果$ARGV[1],则打印“包含$LogRecordCount记录的文件”;
关闭日志文件;
这是一张带有注释的旧代码的图片;

您似乎遇到的问题是,您不确定端口被捕获的位置和哈希更新

发生的事情是,当
循环一次迭代一行文件时,将值捕获到
$LogRecord=~
行正在捕获模式中,
$1
$2

然后,
$2
就是你可以通过
推送
添加到散列中的东西

然而,我在风格方面做了一些改变,比如使用词法文件句柄,因为这是更好的风格

#!/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; 
如果要对它们进行排序,则必须使用
sort
进行排序

现在,
sort
是一个非常聪明的函数,但默认情况下是按字母数字排序。那是。。。实际上,当涉及到IP地址或端口号时,并不是所有这些都很有用,因为您可能希望对它们进行数字排序。简单的答案是
Sort::Naturally
和使用
sensort

但是-
sort
接受一个函数(默认为
cmp
),该函数根据相对位置返回-1、0、1

因此,“按IP”排序可能如下所示:

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;
}
如果IP到端口的映射存在重复项,那么最好还是使用散列而不是数组散列来计算端口频率

$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";
   }
}

您似乎遇到的问题是,您不确定捕获端口的位置和哈希更新

发生的事情是,当
循环一次迭代一行文件时,将值捕获到
$LogRecord=~
行正在捕获模式中,
$1
$2

然后,
$2
就是你可以通过
推送
添加到散列中的东西

然而,我在风格方面做了一些改变,比如使用词法文件句柄,因为这是更好的风格

#!/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; 
如果要对它们进行排序,则必须使用
sort
进行排序

现在,
sort
是一个非常聪明的函数,但默认情况下是按字母数字排序。那是。。。实际上,当涉及到IP地址或端口号时,并不是所有这些都很有用,因为您可能希望对它们进行数字排序。简单的答案是
Sort::Naturally
和使用
sensort

但是-
sort
接受一个函数(默认为
cmp
),该函数根据相对位置返回-1、0、1

因此,“按IP”排序可能如下所示:

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;
}
如果IP到端口的映射存在重复项,那么最好还是使用散列而不是数组散列来计算端口频率

$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";
   }
}

你绝对可以问关于作业的问题——但同样的规则适用于“真实”问题。e、 我们不会为你做作业(家庭作业或其他)。我们将帮助您理解您的问题并修复您正在处理的代码。粘贴一段日志(这样我们就不必从屏幕截图重建)将有助于测试。您不必问问题,也不必得到完美的答案,只需删除所有内容。Stackoverflow不是这样工作的。FYI@Sobrique。堆栈溢出的目的是提供一个参考源。回答你的问题是一个有益的副作用。但重要的是保留问题和答案,这样它可以作为参考。是的,它可以让人们在下学期用谷歌搜索这项作业。但也许他们也有同样的问题。Stackoverflow不是免费的一对一辅导服务。提出问题并得到回答的行为创造了一点以前不存在的知识。Stackoverflow的目的是通过分享这些知识来驱动访问者访问站点。如果这些知识只打算传授给你,我们将作为私人导师为个别提问者提供服务。对于这项服务,你必须付费。你绝对可以询问任务——但同样的规则适用于“真实”问题。e、 我们不会为你做作业(家庭作业或其他)。我们将帮助您理解您的问题并修复您正在处理的代码。粘贴一段日志(这样我们就不必从屏幕截图重建)将有助于测试。您不必问问题,也不必得到完美的答案,只需删除所有内容。Stackoverflow不是这样工作的。FYI@Sobrique。堆栈溢出的目的是提供一个参考源。回答你的问题是一个有益的副作用。但重要的是要保持