IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

parser fichier log + à partir des lignes extraire l'heure minute seconde et calculer une période


Sujet :

Langage Perl

  1. #1
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2011
    Messages : 3
    Points : 1
    Points
    1
    Par défaut parser fichier log + à partir des lignes extraire l'heure minute seconde et calculer une période
    Bonjour Tous mes frères et soeurs

    mon sujet est :
    à partir d'un fichier log je vais extraire tous les lignes de trace dont il y a début de maintenance et fin de maintenance

    exemple des traces que je dois trouvé
    [Tue Feb 08 11:44:22 2011] A maintenance phase begins!
    [Tue Feb 08 11:56:14 2011] Maintenance phase is done!

    [Tue Feb 08 13:49:22 2011] A maintenance phase begins!
    [Tue Feb 08 13:56:14 2011] Maintenance phase is done!


    après dans le début de chaque ligne il y a la date sous cette forme [Tue Feb 08 11:44:22 2011] , je vais extraire l'heure la minute et la seconde et les convertir tous en secondes ( heure * 60 *60 + minutes * 60 + secondes) tous pour chaque ligne début maintenance et fin de maintenance

    çad les deux lignes suivantes :

    [Tue Feb 08 11:44:22 2011] A maintenance phase begins!
    [Tue Feb 08 11:56:14 2011] Maintenance phase is done!


    seront après extraire l'heure et la convertir deux variables :

    3568988 # date de debut maintenance en seconde
    5688987 # date de fin en seconde en seconde

    à la fin je calcule la différence entre début et fin pour avoir la durée de chaque maintenance et les deux lignes seront une seul ligne la durée

    je suis très débutant avec Perl et j'ai commencé par ça : ( je serais Professionnel avec le temps et avec les tutoriaux sur votre site.

    mon code est le suivant et mon besoin d'aide est en commentaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    #!/usr/bin/perl
     
    use strict ;
    use warnings ;
    use Data::Dumper ;
    use Carp ;
     
    sub lire_f($) {
        my $f = shift ;
        open my $IN, "<", $f || return 0 ;
        my $fin ;
     
        while ( my $ligne = <$IN> ) {
    	next if $ligne !~ /[A maintenance phase begins!|Maintenance phase is done!]/;
    # mon problème ici est qu'on m'affiche tous les lignes et moi je veux que les lignes avec ses phrases en dessus 
           my @temp = $ligne;
           my @res = split ( date , $ligne) ;
    #l'extraction de la date de lignes résultats et les convertir en secondes 
    #calculer la différence entre la date de ligne n ( début de maintenance) et la date de la ligne n+1 (fin de maintenance) 
    	push @$fin, @res ;
     
     
        }
        return $fin ;
    }
     
    sub ecrire_f($$) {
        my $f   = shift ;
        my $fin  = shift ;
        open my $OUT, ">", $f || return 0 ;
        print $OUT join("\n",@$fin) ;
        close $OUT ;
        return 1 ;
    }
     
    my $f_in  = "entre.txt" ;
    my $f_out = "sortie.txt" ;
     
    my $fin = lire_f($f_in) ;
    if ( not $fin ) {
        exit 0 ;
    }
     
    my $res = ecrire_f($f_out , $fin) ;
    if ( not $res ) {
         exit 0 ;
    }
     
    exit 1 ;

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Plusieurs soucis dans ton script :
    - l'expression régulière /[A maintenance phase begins!|Maintenance phase is done!]/;
    est incorrecte, car les [ ] servent à définir une classe de caractère, c'est à dire une liste de caractère acceptable comme motif pour 1 caractère, et non pas, comme tu le souhaites, une chaine de caractère. Ainsi, ta regexp devrait être tout simplement : /A maintenance phase begins!|Maintenance phase is done!/;
    - l'affectation my @temp = $ligne est inutile (et inutilisée)
    - le premier paramètre de split n'est ni un identifiant, ni une constante lexicale (une expression régulière par exemple). Une extraire l'heure, minute, seconde, tu as tout intérêt à utilise l'expression suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my ($heure, $minute, $seconde) = $ligne =~ /(\d\d):(\d\d):(\d\d)/;
    - concernant l'usage de "not" (au lieu de !), je ne te le recommande pas. En effet, même si dans ton cas précis, cela ne change rien, il faut savoir qu'il n'a pas du tout la même précédence que l'opérateur ! (priorité très faible). Son usage dans une expression logique à plusieurs membre est donc sujette à erreur si des parenthèses ne sont pas placées autour).
    - par ailleurs, tu utilises une variable scalaire $fin comme référence à un tableau. Pour vérifier si le tableau n'est pas vide, il est préférable d'utiliser l'expression
    plutôt que de simplement vérifier que $fin n'est pas undef. En effet, $fin pourrait être défini avec un tableau vide. Exemple
    Code bash : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $ perl -e 'my $a = [];print qq(Tableau vide\n) if $a;'
    Tableau vide
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  3. #3
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2011
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    D'abord je vous remercie

    on affiche maintenant des lignes dont on a la date en minute

    mais maintenant je vais calculer la difference en minutes entre ligne n et ligne n-1

    exemple :

    text_out.txt actuel après exécuter le code ci-dessous :


    1020.25
    1023.95
    1041.78333333333
    1045.4

    ce que je vais faire maintenant
    line 1 = line 2 - line 1 = 1023.95 - 1020.25
    et prendre un seul chiffre après la virgule

    et le code devient comme ça :
    et il marche très bien

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    #!/usr/bin/perl
     
    use strict ;
    use warnings ;
    use Data::Dumper ;
    use Carp ;
     
    sub read_file($) {
        my $file = shift ;
        open my $IN, "<", $file || return 0 ;
        my $final ;
     
        while ( my $line = <$IN> ) {
    	next if $line !~ /A maintenance phase begins!|Maintenance phase is done!/;
    	my ($heure, $minute, $seconde) = $line =~ /(\d\d):(\d\d):(\d\d)/;
    	my @res = ((($heure * 60) + $minute) * 60 + $seconde) / 60 ;
            #mais maintenant je vais calculer la difference en minutes entre  ligne n        et ligne n-1 
            #exemple @res = line 2 - line 1 = 1023.95 - 1020.25 = 3.7
    	push @$final, @res ;
     
     
        }
        return $final ;
    }
     
     
    sub print_file($$) {
        my $file   = shift ;
        my $final  = shift ;
        open my $OUT, ">", $file || return 0 ;
        print $OUT join("\n",@$final) ;
        close $OUT ;
        return 1 ;
    }
     
    my $file_in  = "text_in.txt" ;
    my $file_out = "text_out.txt" ;
     
    my $final = read_file($file_in) ;
    if ( not $final ) {
        print "A problem occurs while reading file $file_in\n" ;
        exit 0 ;
    }
     
    my $res = print_file($file_out, $final) ;
    if ( not $res ) {
        print "A problem occurs while writing file $file_out\n" ;
        exit 0 ;
    }
     
    exit 1 ;

  4. #4
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    S'il marche, le problème est-il résolu ?
    S'il est résolu, pense à mettre le tag résolu.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  5. #5
    Nouveau Candidat au Club
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Mars 2011
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2011
    Messages : 3
    Points : 1
    Points
    1
    Par défaut
    Ce code il marche

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    #!/usr/bin/perl
     
    use strict ;
    use warnings ;
    use Data::Dumper ;
    use Carp ;
     
    sub read_file($) {
        my $file = shift ;
        open my $IN, "<", $file || return 0 ;
        my $final ;
     
        while ( my $line = <$IN> ) {
    	next if $line !~ /A maintenance phase begins!|Maintenance phase is done!/;
    	my ($heure, $minute, $seconde) = $line =~ /(\d\d):(\d\d):(\d\d)/;
    	my @res = ((($heure * 60) + $minute) * 60 + $seconde) / 60 ;
            #mais maintenant je vais calculer la difference en minutes entre  ligne n        et ligne n-1 
            #exemple @res = line 2 - line 1 = 1023.95 - 1020.25 = 3.7
    	push @$final, @res ;
     
     
        }
        return $final ;
    }
     
     
    sub print_file($$) {
        my $file   = shift ;
        my $final  = shift ;
        open my $OUT, ">", $file || return 0 ;
        print $OUT join("\n",@$final) ;
        close $OUT ;
        return 1 ;
    }
     
    my $file_in  = "text_in.txt" ;
    my $file_out = "text_out.txt" ;
     
    my $final = read_file($file_in) ;
    if ( not $final ) {
        print "A problem occurs while reading file $file_in\n" ;
        exit 0 ;
    }
     
    my $res = print_file($file_out, $final) ;
    if ( not $res ) {
        print "A problem occurs while writing file $file_out\n" ;
        exit 0 ;
    }
     
    exit 1 ;

    mais il me manque comment t calculer la différence entre deux lignes de même fichier çad
    je donne l'exemple

    mon fichier est maintenant comme ça

    12
    30
    35
    43
    78
    98

    je veux maintenant calculer la différence entre chaque deux ligne (2 à 2)

    le résultat ça sera comme ça

    30 -12

    43-35

    98-78

    $n=1 res= $ligne(n+1) - $ligne(n) ; et $n=$n+2 ;
    je sais pas comme faire ça en Perl ?
    j'ai chercher j'ai casser la tête

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Pour écrire seulement les différences de nombre de secondes des lignes, 2 par 2, tu peux modifier la fonction read_file ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    sub read_file($) {
        my $file = shift ;
        open my $IN, "<", $file || return 0 ;
        my $final ;
     
        my $start_time;
        while ( my $line = <$IN> ) {
    	next if $line !~ /A maintenance phase begins!|Maintenance phase is done!/;
    	my ($heure, $minute, $seconde) = $line =~ /(\d\d):(\d\d):(\d\d)/;
            if ($line =~ /is done/) {
              #mais maintenant je vais calculer la difference en minutes entre  ligne n        et ligne n-1 
      	  my $duration = ((($heure * 60) + $minute) * 60 + $seconde) / 60 - $start_time;
    	  push @$final, $duration;
            }
            else {
              $start_time = ((($heure * 60) + $minute) * 60 + $seconde) / 60;
            }
        }
        return $final ;
    }
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

Discussions similaires

  1. Ecrire dans un fichier en sautant des lignes
    Par quefets dans le forum Langage
    Réponses: 4
    Dernier message: 20/11/2008, 15h28
  2. Fichier log : observation des évènements
    Par SylVNR dans le forum VBA PowerPoint
    Réponses: 2
    Dernier message: 05/10/2008, 12h13
  3. Générer un fichier graphviz à partir des tables
    Par louroulou dans le forum VBA Access
    Réponses: 4
    Dernier message: 09/09/2008, 19h09
  4. generation de fichier EXCEL à partir des fichiers .dbf
    Par ergo_proxy dans le forum Collection et Stream
    Réponses: 1
    Dernier message: 19/06/2007, 17h53
  5. [Requête]Creation Colonnes A Partir Des Lignes
    Par elouali dans le forum Requêtes et SQL.
    Réponses: 1
    Dernier message: 25/04/2007, 14h31

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo