Parse log : affucher uniquement les bonnes lignes

Résolu/Fermé
LezardMoo Messages postés 554 Date d'inscription mercredi 5 janvier 2011 Statut Membre Dernière intervention 21 janvier 2015 - Modifié par LezardMoo le 13/01/2014 à 18:06
LezardMoo Messages postés 554 Date d'inscription mercredi 5 janvier 2011 Statut Membre Dernière intervention 21 janvier 2015 - 19 janv. 2014 à 02:56
Bonjour tout le monde !!

je suis en train de faire un petit script d'analyse du fichier log "mail.info"

Voici une première ébauche du script (ce n'est pas définitif, surtout si vous trouvez des choses a redire, je suis preneur ^^)


#!/usr/bin/perl

use strict;
use warnings;
use POSIX qw(strftime);

my $mailog = "mail.info";


open(MAIL,"<$mailog") or die("err open $mailog");
while (my $lines = <MAIL>) {
########## DATE%d ##########
my $date = strftime "%d", localtime;
#my $date = 10;
if($date =~ /0./) {
my @date1 = split(/0/, $date);
print $date1[1];
}else {
print "$date\n";
}
############################

########## USER ##########
my @userSplit = split(/</, $lines);
#print "$userSplit[1]\n";

my @user = split(/@/, $userSplit[1]);
print "$user[0]\n";
##########################

########## TIME ##########
#my @timeSplit = split(/ /,$lines);
#print $timeSplit[4];
my @timeSplit = split(/ /, $lines);
my @time = split(/:/, $timeSplit[3]);
my $realTime = "$time[0]:$time[1]";
print "$realTime\n";

##########################
}
close(MAIL);

Donc voila, dans ce bout de code je récupère en premier lieu la date ensuite le user et pour finir l'heure du log.

Ma demande porte sur l'utilisation de la date ainsi que de l'heure, j'aimerais pouvoir afficher uniquement les lignes contenant la date et l'heure du jour pour ne pas avoir a parser les lignes qui date d'il y a trois semaines(ce qui en plus serait néfaste pour la suite du programme) mais je ne vois pas comment faire.

j'ai testé des trucs du genre


if(/$date/) {}

mais le retour c'est ca


:q!
Use of uninitialized value $_ in print at...

J'ai lu quelque part que ca signifiait que la variable était vide... hum c'est la première à être rempli.... ^^

Merci d'avance ( :





:(){ :|:& };:
A voir également:

3 réponses

[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 13/01/2014 à 18:54
Bonjour LezardMoo,

Tu dis "j'aimerais pouvoir afficher uniquement les lignes contenant la date et l'heure du jour". Je suppose que tu veux dire "j'aimerais pouvoir afficher uniquement les lignes contenant la date du jour"

Peux-tu donner des exemples de lignes de ton "mail.info" ?

Ton format n'a pas l'air d'être le même que le mien sur ma Debian.


Dal
0
LezardMoo Messages postés 554 Date d'inscription mercredi 5 janvier 2011 Statut Membre Dernière intervention 21 janvier 2015 14
14 janv. 2014 à 16:49
Salut Dal,

oui effectivement c'est bien ce que j'ai voulu dire ^^, l'heure me servira après pour detecter le nombre de mails envoyés sur un laps de temps donné.

voici un exemple de ligne de mail.info (je suis aussi sur Debian


Jan 6 18:02:44 testmail postfix/pickup[16791]: 726D543494: uid=0 from=<root>
Jan 7 22:40:54 testmail postfix/pickup[16791]: 745D543445: uid=0 from=<root>
Jan 8 01:08:34 testmail postfix/pickup[16791]: 720D544594: uid=0 from=<root>

donc je voudrais pouvoir afficher uniquement la lignes du 7 janvier
Je suis encore en train de tester, j'ai deja réussis mais impossible de retrouver ce f****ng script...

Il me semble que dedans j'utilisais des regex du genre


if($lines =~ /$date/) {
print lines;
}

mais à l'évidence, ce n'était pas ca puisque ca ne fonctionne pas, il m'affiche $lines sans matcher.

j'ai aussi testé ca


$lines2 = $lines =~ /$date/

marche pas non plus...
0
LezardMoo Messages postés 554 Date d'inscription mercredi 5 janvier 2011 Statut Membre Dernière intervention 21 janvier 2015 14
Modifié par LezardMoo le 14/01/2014 à 17:05
heuuuuuuuuuu bon je vais surement passer pour un con mais j'ai trouvé mon erreur quand je match, je n'ai pas mis de "m" ce FUCKIN "m"

donc


if($lines =~ /$date/) {
print lines;
}
devient

if($lines =~ m/$date/) {
print lines;
}

Si je fais cette erreur bête c'est parce qu'il me semble avoir lu quelque part que dans perl faire m/$pattern/ ou /$pattern/ est la meme chose au niveau du matching.

Donc nouvelle question, cette règle je l'ai inventé ?? ou je confond avec du sed ou un autre langage ?


:(){ :|:& };:
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
14 janv. 2014 à 18:02
https://perldoc.perl.org/perlop#Regexp-Quote-Like-Operators indique que

m/PATTERN/
et
/PATTERN/

sont équivalents et que le m initial est optionnel si le délimiteur de la regexp est bien un slash.

m est l'opérateur regexp pour matcher, lorsque tu le spécifie explicitement, tu peux utiliser une autre paire de caractères que le slash pour délimiter ta regexp (par exemple m#PATTERN#. C'est utile lorsque ta regexp contient elle-même des slashs et que les échapper rendrait la regexp moins lisible.

Dans ton cas, je ne vois pas pourquoi cela aurait un impact.

Sinon, au sujet de ton code, il utilise des splits qui ne sont pas vraiment nécessaires.

c'est plus simple comme cela :

#!/usr/bin/perl

use strict;
use warnings;
use POSIX qw(strftime);
use POSIX qw(strtod setlocale LC_TIME);
setlocale LC_TIME, "C";

my $mailog = "mail.info";

# Date du jour au format C strftime "%b %d"
my $mois = strftime "%b", localtime;
my $jour = strftime "%d", localtime;
# retrait du zéro initial éventuel
$jour =~ s/^0//;

print "E-mails sent on $mois $jour:\n";
open(MAIL,"<$mailog") or die("err open $mailog");
while (my $lines = <MAIL>) {
    if ($lines =~ /$mois\s+$jour\s([0-9]+:[0-9]+:[0-9]+).*<([a-z]+)>/)
    {
        print "$mois $jour at $1 by $2\n"
    }
}
close(MAIL);


Tu peux tester sur ton jeu de test avec :
my $mois = "Jan";
my $jour = "07";


Dal
0
LezardMoo Messages postés 554 Date d'inscription mercredi 5 janvier 2011 Statut Membre Dernière intervention 21 janvier 2015 14
15 janv. 2014 à 17:53
effectivement, je n'ai pas le reflex du perldoc, c'est uniquement quand je tombe dessus dans mes recherches, c'est pas bien...

Merci pour le code, effectivement mes split sont inutiles et alourdissent bien, je vais m'inspirer de ton code pour la suite ^^

Encore Merci pour ton aide bonne continuation à toi ( ;
0
LezardMoo Messages postés 554 Date d'inscription mercredi 5 janvier 2011 Statut Membre Dernière intervention 21 janvier 2015 14
16 janv. 2014 à 15:52
Hi je reviens vers toi, juste pour etre sur, pourrais tu m'expliquer le regex utilisé s'il te plais ??
0
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié par [Dal] le 16/01/2014 à 16:50
Oui :-)

/$mois\s+$jour\s([0-9]+:[0-9]+:[0-9]+).*<([a-z]+)>/


- cherche $mois
- suivi d'un ou plusieurs "caractères blancs", c'est à dire des espaces ou tabulations
- suivis de $jour
- suivi d'un "caractère blanc"
- suivi d'un groupe d'un ou plusieurs chiffres séparés par deux fois deux points (l'heure), et capture cette heure dans $1
- suivis de zéro ou plusieurs caractères
- suivis de <
- suivis d'une ou plusieurs lettres minuscules (le nom d'utilisateur), et capture ce nom dans $2
- suivis de >

Si la ligne matche cette description fournie par la regexp, $1 et $2 contiendront respectivement l'heure et le nom d'utilisateur extraits de la ligne.

Cette regexp est composée sur la base du format de logs que tu as posté.


Dal
0
LezardMoo Messages postés 554 Date d'inscription mercredi 5 janvier 2011 Statut Membre Dernière intervention 21 janvier 2015 14
17 janv. 2014 à 21:48
Merci :D

par contre, cette ligne la
- suivi d'un groupe d'un ou plusieurs chiffres séparés par deux fois deux points (l'heure), et capture cette heure dans $1

La capture dans $1 se fait grace au "+" ? et c'est parce que les "[0-9]+" sont entre parenthèse que chaque plus envoie la valeur dans $1 et ne crée pas $2 et $3 ?

- suivis de zéro ou plusieurs caractères

correspond à cette partie ".*" ?

Merci pour cette explication claire, j'espère que je n'abuse pas trop s:
0