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 :

recherche chaine de caractere dans un fichier texte perl


Sujet :

Langage Perl

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 92
    Points : 26
    Points
    26
    Par défaut recherche chaine de caractere dans un fichier texte perl
    Bonjour,

    J'ai un fichier texte ou les lignes suivantes par exemple apparaissent entre d'autre ligne

    06/11/2014 | 10:39:34.718 | 04176.04052 | INFO | <CResultsState::raffraichirEtat > | Results
    06/11/2014 | 10:39:35.406 | 04176.04052 | INFO | <CPilotage::calculerParamCliniquesBassin > | Pelvis created

    J'aimerais pouvoir faire une recherche dans un if et implémenter un compteur à chaque fois que l'on repère ces deux lignes la qui se
    suivent. J'ai essayé de trouver le code sur les regex mais je n'ai rien trouvé

    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
     
    use strict;
    use warnings;
     
    my $fichier_log = "C:\\Trace_20140610_110725.log";	# Emplacement du fichier "fichier_log"
    my $fichier_txt = "C:\\compteur.txt";	# Emplacement du fichier "fichier_txt"
     
    my $fh_log;
    my $fh_txt;
     
    open ($fh_log, '<', $fichier_log) or die "Impossible d'ouvrir le fichier en lecture";	
    open ($fh_txt, '>', $fichier_txt) or die "Impossible d'ouvrir le fichier en ecriture";
     
    my $cpt;
     
    while(my $ligne = <$fh_log>)
    {
    if ($ligne =~ /Results.*Pelvis created/)#rech results suivi de n caractères suivi de pelvis created (cette commande ne marche pas)
    		{
    		$cpt++;		
    		}
    }
    Merci de votre aide.

  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
    Tu ne peux pas faire un test "multi-line" en parcourant ligne à ligne.
    Par contre, tu peux faire un test en utilisant l'opérateur "d'étendue" .. :

    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
     
    use strict;
    use warnings;
     
    my $fichier_log = "C:\\Trace_20140610_110725.log";	# Emplacement du fichier "fichier_log"
    my $fichier_txt = "C:\\compteur.txt";	# Emplacement du fichier "fichier_txt"
     
    my $fh_log;
    my $fh_txt;
     
    open ($fh_log, '<', $fichier_log) or die "Impossible d'ouvrir le fichier en lecture";	
    open ($fh_txt, '>', $fichier_txt) or die "Impossible d'ouvrir le fichier en ecriture";
     
    my $cpt;
     
    while(my $ligne = <$fh_log>)
    {
      my $in_result = ($ligne =~ /Results/) .. ($ligne =~ /Pelvis created/);
    if ($in_result eq "1E0") #rech results suivi de pelvis created sur la ligne suivante (cette commande devrait marcher)
    		{
    		$cpt++;		
    		}
    }
    S'il peut y avoir plusieurs lignes entre /Results/ et /Pelvis created/, tu peux alléger le test ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($in_result =~ /E0/)
    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 membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 92
    Points : 26
    Points
    26
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Tu ne peux pas faire un test "multi-line" en parcourant ligne à ligne.
    Par contre, tu peux faire un test en utilisant l'opérateur "d'étendue" .. :


    Salut merci de ta réponse mais j'ai essayé ton code avec un test simple et sa ne fonctionne pas

    J'ai testé ce code
    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
     
    use strict;
    use warnings;
     
    my $fichier_log = "C:\\Trace_20140610_110725.log";	# Emplacement du fichier "fichier_log"
    my $fichier_txt = "C:\\compteur.txt";	# Emplacement du fichier "fichier_txt"
     
    my $fh_log;
    my $fh_txt;
     
    open ($fh_log, '<', $fichier_log) or die "Impossible d'ouvrir le fichier en lecture";	
    open ($fh_txt, '>', $fichier_txt) or die "Impossible d'ouvrir le fichier en ecriture";
     
    while(my $ligne = <$fh_log>)
    {
      my $in_result = ($ligne =~ /Results/) .. ($ligne =~ /Pelvis created/);
    if ($in_result eq "1E0")
    		{
    		print "Le code fonctionne\n"
    print $fh_txt "le code fonctionne\n"	
    		}
    }
    Lorsque sa compile rien ne s'affiche, il n'y a pas d'erreur mais le programme ne comprend surement pas ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
       my $in_result = ($ligne =~ /Results/) .. ($ligne =~ /Pelvis created/);
    if ($in_result eq "1E0")
    et du coup il ne reconnait pas lorsque ces deux lignes se suivent


    06/11/2014 | 10:39:34.718 | 04176.04052 | INFO | <CResultsState::raffraichirEtat > | Results
    06/11/2014 | 10:39:35.406 | 04176.04052 | INFO | <CPilotage::calculerParamCliniquesBassin > | Pelvis created

    Voix tu le problème philou ?

    merci.

  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
    Je me suis trompé dans le "1E0" : il faut écrire "2E0".

    Pour expliquer : l'opérateur .. retourne 0 tant que le premier opérande n'est pas vrai (c'est à dire tant que l'on n'a pas trouvé "Results").
    Puis il retourne un nombre commençant par 1 et incrémenté jusqu'à ce que le deuxième opérande soit vrai à son tour (sans tester le premier opérande, et donc, jusqu'à ce que l'on trouve "Pelvis created").
    Lorsque le deuxième opérande devient vrai, l'opérateur .. ajoute la chaine "E0" (E suivi du chiffre 0) derrière le numéro de ligne. Dans ton cas, c'est sur la 2e ligne après la ligne du "Results" (je m'étais trompé en pensant que les indices commençait à 0, ce qui n'est pas le cas). Donc, pour résumer :
    - avant d'arriver sur la ligne Results, $in_result retourne 0 (donc faux si testé dans un if)
    - sur la ligne du Results, $in_result retourne 1 (donc vrai si testé dans un if)
    - sur la ligne Pelvis created, $in_result retourne 2E0 (donc vrai si testé dans un if, et vaut 2 si utilisé en tant que nombre, puisque 2E0 est égal à 2x100 en mathématique). Ici, on teste la présence de "E0" pour savoir si c'est la fin du bloc "Results" ... "Pelvis created", et plus particulièrement, si c'est ce bloc fait 2 lignes (si le bloc avait contenu 3 lignes au lieu de deux, le if aurait échoué).

    Si le bloc à chercher peut contenir d'autres lignes entre "Results" et "Pelvis created", il faudra alors modifier le test comme je l'avais indiqué dans mon post précédant, ainsi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($in_result =~ /E0/)
    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 membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 92
    Points : 26
    Points
    26
    Par défaut Parsing de fichier log en perl
    Citation Envoyé par Philou67430 Voir le message
    Je me suis trompé dans le "1E0" : il faut écrire "2E0".
    Merci !!!! Sa marche nickel, j'ai réussi à faire tous ce que je voulais.
    Sinon j'avais une question, imaginons que je veuille faire le parsing de plusieurs fichiers en même temps, comment je dois m'y prendre ? Parce que dans mes programmes je met ce code
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    my $fichier_log = "C:\\Trace_20140611_100702.log";	# Emplacement du fichier "fichier_log"
    my $fichier_txt = "C:\\FichierLog\\compteur_workflow_temps.txt";	# Emplacement du fichier "fichier_txt"
     
    my $fh_log;
    my $fh_txt;
     
    open ($fh_log, '<', $fichier_log) or die "Impossible d'ouvrir le fichier en lecture";	# Ouverture du fichier pour la lecture
    open ($fh_txt, '>', $fichier_txt) or die "Impossible d'ouvrir le fichier en ecriture";	# Ouverture du fichier pour l'écriture
    Mais il analyse seulement un fichier, moi je voudrais que mon programme analyse plusieurs fichiers en même temps et affiche le résultat soit dans le même nouveau fichier, soit dans des fichiers séparés.
    A tu la solution ?
    Merci

  6. #6
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Tu mets tout ton code pour ouvrir le fichier en entrée, lire le fichier en entrée et refermer le fichier en entrée dans une boucle while qui boucle sur la liste des fichiers en entrée.

  7. #7
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2014
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2014
    Messages : 92
    Points : 26
    Points
    26
    Par défaut
    Citation Envoyé par Lolo78 Voir le message
    Tu mets tout ton code pour ouvrir le fichier en entrée, lire le fichier en entrée et refermer le fichier en entrée dans une boucle while qui boucle sur la liste des fichiers en entrée.

    Merci lolo je vais essayer de faire cela.
    Sinon j'avais une autre question que j'ai posé dans un nouveau topic et peut être que tu pourrais m'aider pour la solution.

    Je poste le lien du topic :
    http://www.developpez.net/forums/d14...l/#post7868832

    Merci

Discussions similaires

  1. Réponses: 2
    Dernier message: 19/10/2012, 13h29
  2. Réponses: 8
    Dernier message: 25/03/2008, 10h42
  3. Réponses: 3
    Dernier message: 25/07/2006, 08h40
  4. Réponses: 10
    Dernier message: 22/05/2006, 11h45

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