|
|||||||||||||||||||||||||||
Jesper Lund wrote:
> Hej,
>
> Jeg er ved at skrive lidt logparser til min ProFTPd log. I den
> frobindelse har jeg fået lavet noget med en hash der ser sådan her ud:
>
> $filnavn{antal gange den er hentet}
>
> Den vil jeg gerne have skrevet ud i nummerorden:
>
> print "<table border=1>\n";
> foreach $i (keys(%filnavn)) {
> print "<tr><td>$i<td>$filnavn{$i}\n";
> }
>
> men der kommer de jo i den rækkefælge de nu lige tilfældigt står i i
> hashen.
>
> Hvis jeg gerne vil have den fil der er downet flest gange øverst i
> tabellen, skal de sorteres efter det tal som man kan angove i hashen.
> Men hvordan ? Findes der en smart funktion, eller skal man selv lave
> noget spaghetti-programmering ?
Jeg ved ikke om du vil kalde det spaghetti-programmering, men her er mit
bud på en løsning.
har man en xferlog der ser sådan her ud (tænkt simplificeret eksempel):
--------------xferlog ------------
kewl linuxsangen.mp3 1234566 11:11
ugh pr0n.mpg 998776 03:42
john_fubar pr0n.mpg 998776 14:02
lamer hacking4dummies.txt 7654 05:24
blah pr0n.mpg 998776 14:02
flip pr0n.mpg 998776 12:19
lamer2 hacking4dummies.txt 7654 05:27
--------end xferlog-----------
og følgende to filer :
#---------FTPLogEntry.pm-----------
package FTPLogEntry;
use Exporter;
use Carp;
@ISA = qw / Exporter / ;
@EXPORT = qw / new / ;
sub new{
my $class = shift;
my $self = {};
$self->{USER} = shift;
$self->{FILE} = shift;
$self->{FILE_SIZE} = shift;
$self->{TIME} = shift;
# her kan man så tilføje flere instans-variabler ( eller hvad man nu har
lyst til at kalde dem)
return bless $self, $class;
}
sub AUTOLOAD{
my $self = shift;
ref $self || croak "$self is not an object :-(";
my $name = $AUTOLOAD;
$name =~ s/.*://;
unless(exists $self->{$name}){croak "no such member: $name"}
return $self->{$name}
}
1;
#----------end FTPLogEntry.pm---------------------
#----------ftplogparser.pl ------------------------
#!/usr/bin/perl
use warnings;
use FTPLogEntry;
use subs qw / by_download / ;
my $files = {};
open LOG, "<xferlog" || die "cannot open xferlog : $!";
while($line = <LOG>){
chomp($line);
my @data = split /\s+/, $line;
unless(@data){next}
my $entry = FTPLogEntry->new(@data);
unless($files->{$entry->FILE}){$files->{$entry->FILE} = []}
push @{$files->{$entry->FILE}}, $entry;
}
close LOG;
@values = values(%{$files});
@ranking = sort by_download @values;
foreach $entry (@ranking){
print "File: ",$entry->[0]->FILE, ", ", scalar(@{$entry}),"
downloads\n";
}
sub by_download{scalar(@{$b}) <=> scalar(@{$a})}
#------------end ftplogparser.pl ---------------
Så får man følgende output ved kørsel af ftplogparser.pl
sslug@sslug perl]$ ./ftplogparser.pl
File: pr0n.mpg, 4 downloads
File: hacking4dummies.txt, 2 downloads
File: linuxsangen.mp3, 1 downloads
sslug@sslug perl]$
Vupti :-)
Christian Hemmingsen
|
||||||||||||||
|
||||||||||||||