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 :

[debutant] extraction fichier log. Pourquoi 1 sur 2 !?!


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut [debutant] extraction fichier log. Pourquoi 1 sur 2 !?!
    Bonjour,

    J'ai un fichier log dont je voudrais extraire des chiffres.
    Le fichier se présente de la manière suivante :
    ...
    Données inutiles
    ***** SAUVEGARDE ETAB 25
    Données inutiles

    Number of files: 40600
    Number of files transferred: 61
    Données inutiles
    ***** SAUVEGARDE ETAB 27
    Données inutiles
    etc.

    Je ne réussis à extraire les données que pour un établissement sur 2 !!!
    Qu'est-ce qui ne va pas dans mon programme?

    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
    #!/usr/bin/perl
     
    print "donnez le nom du fichier :\n";
    $nom_fichier = <STDIN>;
    open SOURCE,$nom_fichier || die "impossible d'ouvrir votre fichier ";
    open DESTINATION, ">resultat_sauv.txt";
     
    print DESTINATION "Etablissement\tNb total fich\tNb fich modif\n";
     
    while ($ligne=<SOURCE>){
     
    	while (($ligne=<SOURCE>)&&(!($ligne =~/([*]{5} SAUVEGARDE ETAB )(.*)/))){};
     
    	if ($ligne =~/([*]{5} SAUVEGARDE ETAB )(.*)/){
    		$nombre = $2;
    		chomp $nombre;
    		$etab = $nombre."\t";
     
    		while (($ligne=<SOURCE>)&&(!($ligne =~/([*]{5} SAUVEGARDE ETAB )(.*)/))){
     
    			if($ligne =~/(Number of files: )(.*)/){
    				$nombre = $2;
    				chomp $nombre;			
    				$total_fic = $2."\t";
    				}
     
    			if($ligne =~/(Number of files transferred: )(.*)/){
    				$nombre = $2;
    				chomp $nombre;			
    				$fic_modif = $2;
    				}
    			}
    	$notice = $etab.$total_fic.$fic_modif;
    	print DESTINATION "$notice\n";
    	}
     
    }
    close SOURCE;
    close DESTINATION;
    Merci par avance.

  2. #2
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Première chose à faire : mettre les balises CODE (j'ai édité ton message pour les rajouter, mais la prochaine fois fais le toi-même) ! Sinon tu réduis de beaucoup les probabilités de recevoir une réponse.

    Sinon ton script est mauvais parce qu'il y a trop de lectures, tu fais parfois 2 lectures à la suite et ignore certaines lignes de ce fait...
    La meilleure solution pour ce genre de problème passe usuellement par une seule boucle de lecture où l'on analyse la ligne, et quelques variables d'états pour spécifier où on en est et comment analyser la ligne :
    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
    52
    53
    54
    55
    56
    57
    58
    59
    #!/usr/bin/perl
    # je te conseille fortement de t'astreindre à plus de rigueur dans tes scripts
    # les deux lignes suivantes t'y aideront 
    use strict;
    use warnings;
     
    print "Donnez le nom du fichier :\n";
    my $nom_fichier = <STDIN>;
    # supprimons le retour à la ligne intempestif
    chomp($nom_fichier);
    # utilise "or" plutôt que "||", ta ligne contenait un bug subtil
    # par ailleurs je te conseille d'utiliser le style d'open() que j'utilise ici, il est 
    # plus sûr et plus flexible
    open my($source), '<', $nom_fichier 
      or die "Impossible d'ouvrir votre fichier $nom_fichier : $!\n ";
    open my($destination), '>', "resultat_sauv.txt"
      or die "Impossible d'ouvrir votre fichier resultat_sauv.txt : $!\n ";
     
    print $destination "Etablissement\tNb total fich\tNb fich modif\n";
     
    # "variables d'état"
    my ($etab, $total_fic, $fic_modif);
     
    while (my $ligne=<$source>){
     
      # ce code sautait automatiquement une ligne à chaque fois...
      # et il n'est pas nécessaire
      # while (($ligne=<SOURCE>)&&(!($ligne =~/([*]{5} SAUVEGARDE ETAB )(.*)/))){};
     
      # ligne signalant le début d'un établissement
      if ($ligne =~ m/^\*{5} SAUVEGARDE ETAB (\d*)/){
        # si on était déjà en train de traiter un établissement
        # on écrit maintenant dans le fichier résultat et on nettoie les variables
        if( $etab ) {
          my $notice = $etab.$total_fic.$fic_modif;
          print $destination "$notice\n";
          ($etab, $total_fic, $fic_modif) = (undef) x 3;
        }
        $etab = $1."\t";
      }
     
      if($ligne =~/Number of files: (\d*)/){	
        $total_fic = $1."\t";
      }
     
      if($ligne =~/Number of files transferred: (\d*)/){		
        $fic_modif = $1;
      }
     
    }
     
    # ne pas oublier le dernier établissement !
    if( $etab ) {
      my $notice = $etab.$total_fic.$fic_modif;
      print $destination "$notice\n";
    }
     
    close $source;
    close $destination;
    --
    Jedaï

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut Excellent !
    Toute une éducation à refaire !
    Evidemment ça fonctionne beaucoup mieux comme ça !
    Un grand merci pour ce cours particulier.

    Restent juste:

    - une confirmation: le m dans
    if ($ligne =~ m/^\*{5} SAUVEGARDE ETAB (\d*)/){
    correspond (?) à l'option
    "traiter la chaîne comme des lignes multiples (^ et $ s'appliqueront à chaque ligne)"
    qu'on aurait pu trouver après /ER/
    (cf FAQ :"Une expression régulière peut être suivie d'options cumulables, qui modifient l'interprétation de l'expression").
    C'est la même chose ?

    - une question:
    mon fichier log exemple comprend un établissement dont la sauvegarde a échoué. Après traitement je me retrouve avec 1 fichier au total, dont 1 modifié (au lieu de 0 et 0). ça ne devrait pas trop modifier mes stat, mais y a-t-il un moyen d'avoir 0 ?

    - une remarque:
    désolé pour les balises CODE. J'avais supprimé cette discussion et j'en avais créé une autre pour avoir la fenêtre, mais je ne connais pas html: j'avais mis [CODE] et [\CODE] à la ligne, ça vient sûrement de là.

    Encore merci pour le temps passé à réécrire mon code.

  4. #4
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par apprenti doc
    Toute une éducation à refaire !
    Evidemment ça fonctionne beaucoup mieux comme ça !
    Un grand merci pour ce cours particulier.

    Restent juste:

    - une confirmation: le m dans
    if ($ligne =~ m/^\*{5} SAUVEGARDE ETAB (\d*)/){
    correspond (?) à l'option
    "traiter la chaîne comme des lignes multiples (^ et $ s'appliqueront à chaque ligne)"
    qu'on aurait pu trouver après /ER/
    (cf FAQ :"Une expression régulière peut être suivie d'options cumulables, qui modifient l'interprétation de l'expression").
    C'est la même chose ?
    Non, rien à voir, en fait /regex/ est équivalent à m/regex/ (m pour match, s pour substitution), j'ai l'habitude d'utiliser plutôt m/regex/ que je trouve légèrement plus lisible, mais je n'ai "corrigé" qu'une seule occurence dans ton script...

    Citation Envoyé par apprenti doc
    - une question:
    mon fichier log exemple comprend un établissement dont la sauvegarde a échoué. Après traitement je me retrouve avec 1 fichier au total, dont 1 modifié (au lieu de 0 et 0). ça ne devrait pas trop modifier mes stat, mais y a-t-il un moyen d'avoir 0 ?
    Comment le fait que la sauvegarde ait échoué se manifeste-t-il ?

    --
    Jedaï

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut
    Citation Envoyé par Jedai
    Comment le fait que la sauvegarde ait échoué se manifeste-t-il ?
    Pour cet établissement, je n'ai pas les lignes
    Number of files:
    Number of files transferred:

    Donc logiquement ne devrais pas avoir 1 dans mes résultats !

  6. #6
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Oui, c'est étrange, en fait tu ne devrait rien avoir (pas même de 0) à part un warning dû au fait que tu essaies de concaténer des valeurs undef...

    C'est assez facile à corriger toutefois :
    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
    52
    53
    54
    55
    56
    57
    58
    59
    #!/usr/bin/perl
    # je te conseille fortement de t'astreindre à plus de rigueur dans tes scripts
    # les deux lignes suivantes t'y aideront 
    use strict;
    use warnings;
     
    print "Donnez le nom du fichier :\n";
    my $nom_fichier = <STDIN>;
    # supprimons le retour à la ligne intempestif
    chomp($nom_fichier);
    # utilise "or" plutôt que "||", ta ligne contenait un bug subtil
    # par ailleurs je te conseille d'utiliser le style d'open() que j'utilise ici, il est 
    # plus sûr et plus flexible
    open my($source), '<', $nom_fichier 
      or die "Impossible d'ouvrir votre fichier $nom_fichier : $!\n ";
    open my($destination), '>', "resultat_sauv.txt"
      or die "Impossible d'ouvrir votre fichier resultat_sauv.txt : $!\n ";
     
    print $destination "Etablissement\tNb total fich\tNb fich modif\n";
     
    # "variables d'état"
    my ($etab, $total_fic, $fic_modif) = (undef,  "0\t", "0");
     
    while (my $ligne=<$source>){
     
      # ce code sautait automatiquement une ligne à chaque fois...
      # et il n'est pas nécessaire
      # while (($ligne=<SOURCE>)&&(!($ligne =~/([*]{5} SAUVEGARDE ETAB )(.*)/))){};
     
      # ligne signalant le début d'un établissement
      if ($ligne =~ m/^\*{5} SAUVEGARDE ETAB (\d*)/){
        # si on était déjà en train de traiter un établissement
        # on écrit maintenant dans le fichier résultat et on nettoie les variables
        if( $etab ) {
          my $notice = $etab.$total_fic.$fic_modif;
          print $destination "$notice\n";
          ($total_fic, $fic_modif) = ("0\t", "0");
        }
        $etab = $1."\t";
      }
     
      if($ligne =~/Number of files: (\d*)/){	
        $total_fic = $1."\t";
      }
     
      if($ligne =~/Number of files transferred: (\d*)/){		
        $fic_modif = $1;
      }
     
    }
     
    # ne pas oublier le dernier établissement !
    if( $etab ) {
      my $notice = $etab.$total_fic.$fic_modif;
      print $destination "$notice\n";
    }
     
    close $source;
    close $destination;

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut ????????
    Citation Envoyé par Jedai
    Oui, c'est étrange, en fait tu ne devrait rien avoir (pas même de 0) à part un warning dû au fait que tu essaies de concaténer des valeurs undef...[/CODE]

    Je ne comprends pas ! Je suis bien d'accord que je n'aurais même pas du avoir 0 avec le programme précédent. J'ai bien compris le sens de ta correction... Mais j'ai toujours (étab) 50, (total_fic) 1, (fic_modif) 1.
    Cela viendrait-il du fait que c'est mon premier établissement et que le SERVEUR juste avant a lui ces valeurs?... Oui! c'est ça. J'ai modifié mon fichier source : en mettant 2 et 2 pour le serveur 1, je les retrouve dans les résultats en face de l'étab 50 !!! Pourtant les autres ne sont pas décalés.
    Alors pourquoi ?

    ***** SAUVEGARDE SERVEUR1
    (...)
    Number of files: 1
    Number of files transferred: 1
    (...)
    ***** SAUVEGARDE ETAB 50
    (...)
    rsync: connection unexpectedly closed (0 bytes received so far) [receiver]
    rsync error: unexplained error
    ***** SAUVEGARDE ETAB 17
    (...)

  8. #8
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Ok, comme je ne me doutais pas qu'on risquait de rencontrer ces lignes en dehors d'un établissement, je ne m'étais pas méfié... Voici une version qui évite ce problème en ne prenant en compte ces lignes que si l'on est en train de traiter un établissement :
    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
    52
    53
    54
    55
    56
    57
    58
    59
    #!/usr/bin/perl
    # je te conseille fortement de t'astreindre à plus de rigueur dans tes scripts
    # les deux lignes suivantes t'y aideront 
    use strict;
    use warnings;
     
    print "Donnez le nom du fichier :\n";
    my $nom_fichier = <STDIN>;
    # supprimons le retour à la ligne intempestif
    chomp($nom_fichier);
    # utilise "or" plutôt que "||", ta ligne contenait un bug subtil
    # par ailleurs je te conseille d'utiliser le style d'open() que j'utilise ici, il est 
    # plus sûr et plus flexible
    open my($source), '<', $nom_fichier 
      or die "Impossible d'ouvrir votre fichier $nom_fichier : $!\n ";
    open my($destination), '>', "resultat_sauv.txt"
      or die "Impossible d'ouvrir votre fichier resultat_sauv.txt : $!\n ";
     
    print $destination "Etablissement\tNb total fich\tNb fich modif\n";
     
    # "variables d'état"
    my ($etab, $total_fic, $fic_modif) = (undef,  "0\t", "0");
     
    while (my $ligne=<$source>){
     
      # ce code sautait automatiquement une ligne à chaque fois...
      # et il n'est pas nécessaire
      # while (($ligne=<SOURCE>)&&(!($ligne =~/([*]{5} SAUVEGARDE ETAB )(.*)/))){};
     
      # ligne signalant le début d'un établissement
      if ($ligne =~ m/^\*{5} SAUVEGARDE ETAB (\d*)/){
        # si on était déjà en train de traiter un établissement
        # on écrit maintenant dans le fichier résultat et on nettoie les variables
        if( $etab ) {
          my $notice = $etab.$total_fic.$fic_modif;
          print $destination "$notice\n";
          ($total_fic, $fic_modif) = ("0\t", "0");
        }
        $etab = $1."\t";
      }
     
      if($etab and $ligne =~/Number of files: (\d*)/){	
        $total_fic = $1."\t";
      }
     
      if($etab and $ligne =~/Number of files transferred: (\d*)/){		
        $fic_modif = $1;
      }
     
    }
     
    # ne pas oublier le dernier établissement !
    if( $etab ) {
      my $notice = $etab.$total_fic.$fic_modif;
      print $destination "$notice\n";
    }
     
    close $source;
    close $destination;

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    33
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 33
    Points : 18
    Points
    18
    Par défaut Magnifique !
    Je te remercie. Je n'ai pas encore pu tester mais ça me paraît limpide et efficace!

  10. #10
    Membre à l'essai
    Inscrit en
    Mars 2007
    Messages
    20
    Détails du profil
    Informations forums :
    Inscription : Mars 2007
    Messages : 20
    Points : 14
    Points
    14
    Par défaut bonjour
    merci de votre réponse.
    mais est ce que vous avez déja travaillé avec talend?en fait il ya pas mal d'outils d'extraction open source qui font l'extraction mais mon problème c 'est que j'ai jamais travaillé avec ses outils.c'est ma première expérience en décisionnel.j'ai du mal à choisir l'outil convenable.pour choisir un outil il faut le tester mais en ce moment j'ai pas assez de temps pour tester tous les outils .je suis bloqué dans la phase du choix de l'outil.est ce que vous pouvez m'aider la dessus.
    et merci d'avance

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Extraction fichier log
    Par nox73 dans le forum Langage
    Réponses: 9
    Dernier message: 27/05/2010, 12h36
  2. Comment demarrer l'ecriture sur les fichiers log
    Par Lgman dans le forum Administration
    Réponses: 1
    Dernier message: 05/08/2009, 17h05
  3. Consulter les fichiers logs des transaction sur SQL Server 2005
    Par technopole dans le forum Administration
    Réponses: 2
    Dernier message: 17/09/2008, 19h24
  4. Accès concurents sur fichier log
    Par Amnesiak dans le forum Langage
    Réponses: 7
    Dernier message: 08/02/2006, 23h00
  5. [debutant] Visualiser le log sur ma console
    Par nicoo dans le forum Logging
    Réponses: 7
    Dernier message: 21/09/2005, 11h38

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