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 :

Analyser fichiers textes puis remplir tableau


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 36
    Par défaut Analyser fichiers textes puis remplir tableau
    Bonjour à tous,
    Je viens de récupérer 10000 fichiers textes cette nuit après avoir lancé des expérimentations. Maintenant la phase la plus drôle commence : je dois récupérer les résultats de ces fichiers dans un tableur (excel ou openoffice) afin de synthétiser mes résultats.

    Dans chaque fichiers je dois récupérer des compteurs et le temps. Tout mes fichiers ont la même structure mais pas forcément le même nombre de lignes.

    Exemple de fichiers :
    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
     
    Nom algo :
     
    param 1 : valeur
    param 2 : valeur 
    param 3 : valeur
     
    Nombre de candidats de taille 1
    Nombre de candidats de taille 2
    ... (on ne connait pas la taille max des candidats)
     
    Nb résultats de type1 : nbrésultat1
     
    Liste :
    1er résultat de type 1
    2ème résultat de type 1
    ... (il y a nbrésultat et donc autant de lignes)
     
    Nb résultats de type 2 : nbrésultat2
     
    Liste :
    1er résultat de type 2
    2ème résultat de type 2
    ... (il y a nbrésultat2 et donc autant de lignes)
    compteur 1 : ct1
    compteur 2 : ct2
    compteur 3 : ct3
     
    Nb résultats de type 3 : nbrésultat3
     
    Liste :
    1er résultat de type 3
    2ème résultat de type 3
    ... (il y a nbrésultat3 et donc autant de lignes)
     
    Temps :
    real : temps1
    user : temps2
    sys : temps3
    Dans un fichier de ce type, j'aimerais récupérer les différentes valeurs des paramètres, nbrésultat1, ct1, ct2, ct3, nbrésultat3 et enfin les temps real, user et sys.

    Je ne sais pas du tout par où commencer, quel langage dois je utiliser? Perl, python, autres? Je ne sais pas non plus comment créer un fichier excel (ou openoffice) quelque soit le langage. Avez vous une piste à me suggérer ou un bout de code déjà fonctionnel ?

    Bonne journée

  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 : 59
    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
    Par défaut
    Le plus simple, me semble-t-il est de créer des fichiers CSV (ou TSV) en les créant simplement avec des print suite à la lecture séquentielle de tes fichiers d'entrée.
    Pour aller plus loin avec un exemple de script, il faudrait que tu détailles plus ce qu'il faut vraiment récupérer (de manière exhaustive), et donner un exemple réel, notamment pour savoir si les textes permettant d'identifier les valeurs à extraire sont bien ceux que tu donnes.

  3. #3
    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
    Billets dans le blog
    1
    Par défaut
    Ce que tu veux faire semble tout-à-fait réalisable en Perl, et même relativement simple. Je dirais même que Perl est très adapté à ce genre de traitement de données. Mais je ne doute pas que ce soit possible également en Python.

    Pour info, il existe plusieurs module Perl permettant d'écrire directement des fichiers Excel, Open Office ou autres. Mais l'idée de créer un fichier CSV est aussi une solution très simple (et, en un sens, plus générale, car adaptée à n'importe quel tableur), car les tableurs savent bien ouvrir les CSV.

    Je rejoins Philou: l'essence de la manipulation de données, en Perl comme dans un autre langage, est de très bien connaître les données en entrée et leur format, ainsi que les cas particuliers éventuels. Un exemple réel (quitte à anonymiser certaines choses si nécessaire) serait donc très utile.

  4. #4
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 36
    Par défaut
    Merci pour ta réponse Philou
    Après recherches, je pense effectivement que c'est plus simple de passer par un fichier csv.

    Et comme demandé voilà un exemple réel :
    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
     
     
    Eureka
     
    Param 1: 0.2
    Param 2: 0.9
    Param 3: 0.2
    Param 4: 0.9
    Param 5: 0.3
     
     
    Size of set of candidate itemsets C(1): 5
    Size of set of candidate itemsets C(2): 4
     
    Number of positive rules found: 8
     
    Positive rules:
     
    1. A=1 2 ==> C=1 2    <conf:(1)>    <MG:(0.33)>
    2. D=1 1 ==> A=1 1    <conf:(1)>    <MG:(1)>
    3. E=1 3 ==> B=1 3    <conf:(1)>    <MG:(0.33)>
    4. B=1 3 ==> E=1 3    <conf:(1)>    <MG:(0.33)>
    5. D=1 1 ==> C=1 1    <conf:(1)>    <MG:(0.33)>
    6. C=1 D=1 1 ==> A=1 2    <conf:(1)>    <MG:(1)>
    7. A=1 D=1 1 ==> C=1 1    <conf:(1)>    <MG:(0.33)>
    8. D=1 1 ==> A=1 C=1 1    <conf:(1)>    <MG:(1)>
     
    Number of negative rules found: 5
     
    Negative rules:
     
    1. !(C=1 3) ==> !(A=1 2) 3    <conf:(1)>    <MG:(1)>
    2. !(A=1 2) ==> !(D=1 1) 3    <conf:(1)>    <MG:(0.33)>
    3. !(E=1 3) ==> !(B=1 3) 3    <conf:(1)>    <MG:(1)>
    4. !(B=1 3) ==> !(E=1 3) 3    <conf:(1)>    <MG:(1)>
    5. !(C=1 3) ==> !(D=1 1) 3    <conf:(1)>    <MG:(0.33)>
    number of rules of type 1 : 0
    number of rules of type 2 : 0
    number of rules of type 3 : 5
     
    Number of conjonction negative rules found: 8
     
    Conjonction negative rules:
     
    1. nonConjonction(C=1 3) ==> nonConjonction(A=1 2)    <conf:(1)>    <MG:(1)>
    2. nonConjonction(A=1 2) ==> nonConjonction(D=1 1)    <conf:(1)>    <MG:(0.33)>
    3. nonConjonction(E=1 3) ==> nonConjonction(B=1 3)    <conf:(1)>    <MG:(1)>
    4. nonConjonction(B=1 3) ==> nonConjonction(E=1 3)    <conf:(1)>    <MG:(1)>
    5. nonConjonction(C=1 3) ==> nonConjonction(D=1 1)    <conf:(1)>    <MG:(0.33)>
    6. nonConjonction(C=1 D=1 1) ==> nonConjonction(A=1 2)    <conf:(1)>    <MG:(1)>
    7. nonConjonction(A=1 C=1 2) ==> nonConjonction(D=1 1)    <conf:(1)>    <MG:(0.33)>
    8. nonConjonction(C=1 3) ==> nonConjonction(A=1 D=1 1)    <conf:(1)>    <MG:(1)>
     
    === Evaluation ===
     
    real 0.05
    user 0.12
    sys 0.01
    Comme je l'ai dit dans mon premier message, je veux récupérer les valeurs :
    - des paramètres aux lignes 5, 6, 7, 8 et 9,
    - le nombre de règles positives à la ligne 15
    - les trois compteurs aux lignex 37, 38 et 39
    - le nombre de règles de conjonction négatives à la ligne 41
    - et les temps real user et sys aux lignes 56, 57 et 58.

    Ces informations ne sont pas toutes aux mêmes lignes dans tous les fichiers.

    à 14h27 : Je viens juste de voir ton message Lolo. Merci également pour ton aide.

  5. #5
    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
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    voici un exemple partiel non testé utilisant une série d'expressions régulières pour analyser les lignes en entrée et alimenter des variables qui peuvent ensuite être utilisées pour alimenter un fichier CSV..

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    my (@param, $nb_positive_rules, @number_of_rules_type, $number_conjunction_neg_rules);
    while (my $line = <$INPUT_DATA>) {
         chomp $line; 
         $param[$1] = $2 if $line =~ /^Param (\d+):\s+([0-9.]+)$/; # traite les params
         $nb_positive_rules = $1 if $line =~ /^Number of positive rules found:\s+(\d+)$/; # traite les règles positives
         $number_of_rules_type[$1] = $2 if $line =~ /^number of rules of type\s+(\d+):\s+(\d+)$; 
         $number_conjunction_neg_rules = $1 if /^Number of conjonction negative rules found:\s+(\d+)$;
         # etc.
    }
    N'hésite pas à demander si tu as besoin d'explications supplémentaires sur le code ci-dessus ou sur la façon de le compléter.

  6. #6
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mars 2008
    Messages
    36
    Détails du profil
    Informations personnelles :
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mars 2008
    Messages : 36
    Par défaut
    Merci beaucoup pour ton aide, mais tu vas un peu trop vite pour moi. Je débute juste en perl, et ta réponse comporte beaucoup d'éléments nouveaux pour moi. Peux tu m'expliquer en détail stp?

  7. #7
    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
    Billets dans le blog
    1
    Par défaut
    OK, je remets le code avec des commentaires explicatifs.

    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
    my (@param, $nb_positive_rules, @number_of_rules_type, $number_conjunction_neg_rules);
    # la ligne précédente déclare quatre variables, deux sont en fait des tableaux de variables 
    # (@param et @number_of_rules_type), les deux autres de simples scalaires
    while (my $line = <$INPUT_DATA>) { #lit un des fichier en entrée. A chaque itération de la boucle, la variable $line prend pour valeur l'une des lignes du fichier
         chomp $line; # enlève le retour à la ligne en fin de ligne (rend plus sûrs les traitements ultérieurs)
         $param[$1] = $2 if $line =~ /^Param (\d+):\s+([0-9.]+)$/; # traite les params. 
    # La ligne précédente recherche si la ligne commence par le mot Param, suivi d'un espace et d'un ou plusieurs chiffres, 
    # suivis d'un ":", d'un ou plusieurs espaces, d'un certain nombre de chiffres et ou de points constituant la fin de la ligne. 
    # en cas de reconnaissance, le premier groupe de chiffres constituera l'indice dans le tableau @param et le second groupe de chiffre la valeur associée à cet indice.
         $nb_positive_rules = $1 if $line =~ /^Number of positive rules found:\s+(\d+)$/; # traite les règles positives
    # la ligne précédente cherche à reconnaître la chaîne de caractères "Number of positive rules found:" en début de ligne
    # suivie par un ou plusieurs espaces, puis par un groupe de chiffre en fin de ligne. Le groupe de chiffre sera affecté à la variable $nb_positive_rules.
         $number_of_rules_type[$1] = $2 if $line =~ /^number of rules of type\s+(\d+):\s+(\d+)$; 
    # la ligne précédente suit à peu près le même principe que la première expression régulière
         $number_conjunction_neg_rules = $1 if /^Number of conjonction negative rules found:\s+(\d+)$;
    # la ligne précédente suit à peu près le même principe que la deuxième expression régulière
         # etc.
    }
    A noter pour la bonne compréhension que les variables $1 et $2 contiennent respectivement le premier groupe de caractères reconnus entre paranthèses et le second groupe de caractères reconnus entre parenthèses.

    Construisons ensemble la dernière série d'expressions régulières.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    real 0.05
    user 0.12
    sys 0.01
    Ligne 1: je recherche le mot "real" en début de ligne, suivi d'un ou plusieurs espaces, suivi d'un nombre sous la forme d'un ou plusieurs chiffres, suivi d'un ".", suivi de deux chiffres en fin de ligne. Et je cherche à capturer le nombre dans une variable.

    - début de ligne: ^
    - Le mot "real": real
    - un ou plusieurs espaces: \s+ (\s est un caractère d'espacement, + signifie qu'il en faut au moins un)
    - un ou plusieurs chiffres, un ., deux chiffres: \d+\.\d\d. Mais comme je veux capturer le contenu, je mets l'ensemble entre parenthèses: "(\d+\.\d\d)".
    - fin de ligne: $

    Ceci donne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $real = $1 if $line =~ /^real\s+(\d+\.\d\d)$/;
    Le début de la ligne donne à la variable $real la valeur de $1, à savoir le groupe de chiffres capturés entre parenthèses.

    De même pour les deux dernières lignes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $utilisateur = $1 if $line =~ /^user\s+(\d+\.\d\d)$/;
    $systeme = $1 if $line =~ /^sys\s+(\d+\.\d\d)$/;
    Pour que ça marche, il faut encore déclarer les trois nouvelles variables ($real, $utilisateur et $systeme) avant la boucle while. Ce qui donne le code suivant, assurant l'ensemble de l'analyse d'un fichier en entrée (toujours non testé):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    my (@param, $nb_positive_rules, @number_of_rules_type, $number_conjunction_neg_rules, $real, $utilisateur, $systeme);
    while (my $line = <$INPUT_DATA>) {
         chomp $line; 
         $param[$1] = $2 if $line =~ /^Param (\d+):\s+([0-9.]+)$/;
         $nb_positive_rules = $1 if $line =~ /^Number of positive rules found:\s+(\d+)$/;
         $number_of_rules_type[$1] = $2 if $line =~ /^number of rules of type\s+(\d+):\s+(\d+)$; 
         $number_conjunction_neg_rules = $1 if /^Number of conjonction negative rules found:\s+(\d+)$;
         $real = $1 if $line =~ /^real\s+(\d+\.\d\d)$/;
         $utilisateur = $1 if $line =~ /^user\s+(\d+\.\d\d)$/;
         $systeme = $1 if $line =~ /^sys\s+(\d+\.\d\d)$/;
    }
    Les variables @param, $nb_positive_rules, @number_of_rules_type, $number_conjunction_neg_rules, $real, $utilisateur et $systeme contiennent maintenant toutes les informations dont tu as besoin pour alimenter ton fichier CSV (ou Excel).

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

Discussions similaires

  1. Réponses: 8
    Dernier message: 29/01/2015, 16h08
  2. Réponses: 1
    Dernier message: 18/10/2009, 19h50
  3. Réponses: 20
    Dernier message: 23/03/2006, 17h21
  4. [Tableaux] Stocker un fichier texte dans un tableau
    Par clairette59 dans le forum Langage
    Réponses: 13
    Dernier message: 28/01/2006, 00h48
  5. Réponses: 5
    Dernier message: 15/05/2005, 09h51

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