#!/usr/bin/perl # strict si warnings ca asa e frumos cand nu scrii mizerii in consola use strict; use warnings; # asta e disponibila doar in perl 5.10, in CLI e adusa de folosirea switchului # -E in loc de -e; e mai fun ca e mai scurt decat print si ca adauga \n automat # fara sa folosesc -l use feature 'say'; my %refs; my %ips; # <> fara argumente e "magic", citeste o linie din fisierul dat ca argument sau # daca nu exista, de la stdin # de notat ca in cli in loc de: # perl -e 'while (<>) { bla-bla } foo' fisier # se poate scrie: # perl -ne ' bla-bla; END { foo }' fisier while (<>) { # extragem ip-ul sursa si referrerul, pozitiile depind de formatul logului my ( $ip, $ref ) = (split)[ 0, 10 ]; # simple, yet magic, populez hashul cu ip-uri, tinand cont de cate vizite au fost $ips{$ip}++; #prelucram putin referrerul inainte, ii scoatem ghilimelele si argumentele $ref =~ s/"//g; $ref =~ s/\?.*//; # sarim peste referinte interne (/prolinux.ro/), din mediul de dev # (/prolinux-dev/) si cele goale (/^-$/) $refs{$ref}++ unless ( $ref =~ /prolinux(\.ro|-dev)|^-$/ ); } # si acum rapoartele: # mai intai ii numaram pe cei cu mai mult de 10 accese (cam jumatate de ip-uri # sunt boti si alte pinguri) # (values %ips) produce o lista cu numarul de accese # (grep { $_ >10 } @lista) produce sublista cu valorile mai mari de 10 # (scalar @lista) produce numarul de valori say "Total visitors: ", scalar grep { $_ > 10 } values %ips; say "-" x 20; # aici apare vestitul "schwarzian transform": # (keys %refs) produce lista de referrers # ( sort { sub } lista ) sorteaza @lista facand comparatii folosind subrutina # cu pricina, care primeste ca argumente $a si $b cu doi membri oarecare ai # listei # ( $refs{$b} <=> $refs{$a} ) compara valorile hashului cu cheile date (in # cazul de fata sorteaza dupa numarul de accese) # acum ca avem lista de referrers sortata, ( foreach @lista ) populeaza $_ cu # valori din lista (aka. un referrer) say "$refs{$_} : $_" foreach ( sort { $refs{$b} <=> $refs{$a} } keys %refs )