2017-05-18 1 views
0

Ich weiß nicht, ob Sie Fragen zu einer Schulaufgabe stellen dürfen. Ich möchte nur verstehen, was ich tun soll, nicht das für mich tun. Vielleicht verpasse ich etwas so Einfaches, dass es direkt vor mir liegt, aber irgendwie basierte es auf einem älteren Auftrag, aber ich hatte diesen Kurs verpasst und ich renne jetzt in eine Wand, und das Problem ist, dass ich es versuche ein Array in eine Hash-Tabelle zu schieben. etwas so verwenden;Wie kann ich in Perl Arrays als Werte in einem Hash speichern?

push @{$hash_table{$hash_key}}, $port 

und die Ports zu zählen, während sie zu speichern und dann den Inhalt des Hash drucken

while (($key , $value) = each (%hash)) { 
    print “$key scanned @{$value}” 
} 

und wenn ich die Ergebnisse sortiert werden wollte würde ich

< foreach $key (keys (%hash)) { 
} 

Die Verwendung aktueller Code, den ich habe, ist dies, Suche nach der Zeichenfolge von/iNext-DROP/ mit einer Protokolldatei zur Verfügung gestellt. Ich kann nicht für das Leben von mir den richtigen Ort finden Sie den Code oben

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; 

Hier ist ein Bild von dem alten Code mit Kommentaren zu addieren;

+0

sind Sie absolut über Zuweisungen erlaubt zu fragen - gelten die gleichen Regeln wie für 'echte' Fragen though. z.B. Wir werden Ihre Arbeit (Hausaufgaben oder andere) nicht für Sie erledigen. Wir werden Ihnen helfen, Ihr Problem zu verstehen und den Code, an dem Sie arbeiten, zu beheben. – Sobrique

+0

Ein Schnipsel mit Protokoll eingefügt (so müssen wir nicht aus Screenshot rekonstruieren) würde zum Testen helfen. – Sobrique

+0

Kommentare formatieren nicht gut [bearbeiten] Sie Ihren Beitrag damit bitte. – Sobrique

Antwort

3

Die Sache, mit der Sie scheinbar Probleme haben, ist, dass Sie nicht sicher sind, wo der Port erfasst wird und das Hash-Update.

Was passiert, ist Ihre while Schleife die Datei eine Zeile zu einem Zeitpunkt iteriert und Werte erfassen - das $LogRecord =~ Linie ein Muster aufzeichnet - in $1 und $2.

Und dann das $2 ist die Sache, die Sie zu Ihrem Hash hinzufügen können, mit push.

Es gibt jedoch ein paar Dinge, die ich Stil weise wie lexikalische Dateigriffe geändert haben, weil es besser Stil ist.

#!/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; 

Das ist Ihre Hashes aufgebaut.

Aber wenn es darum geht, outputing:

foreach my $ip (keys %ports_from) { 
    print "$ip: ", join (" ", @{$ports_from{$ip}}) ,"\n" 
} 

Wenn Sie sie sortieren wollten, würden Sie diese sort mit zu tun haben.

Jetzt sort ist eine ziemlich clevere Funktion, aber standardmäßig wird alphanumerisch sortiert. Das ist ... eigentlich nicht so nützlich, wenn es um IP-Adressen oder Portnummern geht, weil Sie diese wahrscheinlich numerisch sortieren wollen. Die einfache Antwort ist Sort::Naturally und nsort verwenden.

Allerdings - sort nimmt eine Funktion (standardmäßig cmp), die -1, 0, 1 zurückgibt, abhängig von der relativen Position.

So Sortierung 'von IP' könnte wie folgt aussehen:

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

Und dann konnte man:

foreach my $ip (sort by_ip keys %ports_from) { 
    print "$ip: ", join (" ", sort { $a <=> $b } @{$ports_from{$ip}}),"\n"; 
} 

Geben Sie:

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 

Da ein IP-to- Port-Mapping, wo jedoch Duplikate existieren, ist es vielleicht besser, nur Port-Häufigkeit zu zählen, indem ein Hash-of-Hashes anstelle eines Hash-o verwendet wird f-Arrays.

$count_ports_from{$source}{$src_port}++; 

Und dann:

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

Geben Sie so etwas wie:

24.64.208.134 :  24128 : 3 
71.228.199.109 :  37091 : 1 
72.197.8.56 : 9258 : 1 
75.117.31.43 : 3122 : 1 
99.248.20.48 : 48725 : 1 
207.68.178.56 :  80 : 1 
+0

Wow, danke für diese Erklärung, es hilft, ich denke, ich sollte jetzt von hier aus okay sein. –

+0

Ich denke, das Sortieren hat mir mehr geschadet als gut. –

+1

Vielleicht. Eine Standard-Sortierung ist nicht so nützlich wie es mit IPs und Zahlen klingt - Sie brauchen oft etwas Spezifischeres. – Sobrique

Verwandte Themen