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 :

[PERL] traitement fichier texte


Sujet :

Langage Perl

  1. #1
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 6
    Points : 3
    Points
    3
    Par défaut [PERL] traitement fichier texte
    Bonsoir à tous,

    Je m'interesse tout particulierement à ce language pour le traitement de fichier texte.
    voici mon souci:
    je recupere un fichier texte de la forme suivante

    NOM, PRENOM (InitialeDuPoste) EQUIPE Mois Jour, ANNEE Ville, Etat, Nationalite

    c'est le format originale avec espace et virgule presentent

    voici un exemple:
    BEAUX, PAUL (D) ANA Jun 4, 1924 Sorel, QC, CAN

    il a comme nom BEAUX prenom PAUL, c'est un defenseur (Initiale du poste D), je voudrais avoir son age donc 2006-1924, et la nationalite, ici canadien

    Je voudrais donc recuperer dans un autre fichier simplement les infos suivantes et les separer par des points virgules

    NOM;PRENOM;InitialeDuPoste,Age,Pays

    c'est à dire
    BEAUX;PAUL;D;82;CAN

    J'ai commencé à faire un bout de script mais je me melange et c'est plutot complique !! en tout cas pour moi

    Merci de me donner un coup de main

  2. #2
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    172
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 172
    Points : 208
    Points
    208
    Par défaut
    Salut,

    si ton fichier contient que des lignes de genre
    BEAUX, PAUL (D) ANA Jun 4, 1924 Sorel, QC, CAN
    alors tu peux essayer ce script
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/usr/bin/perl
    #
    use warnings;use strict;
     
    open LIRE,"fichier.txt" or die "E/S : $!\n";
    open ECRIRE, ">","resultat.txt" or die "E/S : $!\n";
     
    while (<LIRE>) {
      my @res = split /[,() ]/,$_;
      next unless /^\w/;
      print ECRIRE (join ";",@res[0,2,4]) . ";${\((localtime)[5]+1900 - $res[10])};$res[15]";
    }
    Le resultat
    lami20j@debian:~/trash$ cat fichier.txt
    BEAUX, PAUL (D) ANA Jun 4, 1924 Sorel, QC, CAN
    HANDSOME, PAUL (D) ANA Jul 14, 1934 Sorel, PR, FRA
    PETIT, PAUL (D) ANA Mai 24, 1930 Sorel, QC, BEL
    lami20j@debian:~/trash$ perl dvz_osiris73_020506.pl
    lami20j@debian:~/trash$ cat resultat.txt
    BEAUX;PAUL;D;82;CAN
    HANDSOME;PAUL;D;72;FRA
    PETIT;PAUL;D;76;BEL
    lami20j@debian:~/trash$
    sinon il faut afficher ton fichier pour voir la structure complète.

    lami20j

    P.S. Ce n'est qu'une façon de le faire (TMTOWTDI)
    --
    lami20j

  3. #3
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    merci lami20j pour ta réponse qui je dois l'avouer ma permis de comprendre plein de choses

    en fait le fichier texte est mal formaté, voici un exemple, j'ai donc differentes tabulations et espace dans mon fichier

    BEAUCHEMIN, FRANCOIS (D) ANA Jun 4, 1980 Sorel, QC, CAN
    BRENNAN, KIP (L) ANA Aug 27, 1980 Kingston, ON, CAN
    GIGUERE, JEAN-SEBASTIEN (G) ANA May 16, 1977 Montreal, QC, CAN GILLIES, TREVOR (L) ANA Jan 30, 1979 Cambridge, ON, CAN
    HEDSTROM, JONATHAN (R) ANA Dec 27, 1977 Skelleftea, SWE
    KONDRATIEV, MAXIM (D) ANA Jan 20, 1983 Togliatti, RUS
    KONOPKA, ZENON (C) ANA Jan 2, 1981 Niagara On The Lake, ON, CAN

    quand je prends l'exemple de KONOPKA Zeon il est né dans la ville Niagara On The Lake et donc plusieurs espaces, j'ai fait le script suivant (et oui désolé je suis sous W$ qui fonctionne :

    #!c:\perl\bin\perl.exe -w
    use warnings;use strict;

    print "quel fichier source ?";
    my $source = <STDIN>;

    print "quel fichier destination ?";
    my $destination=<STDIN>;

    print "Quelle est l'annee ?";
    my $annee=<STDIN>;

    open (LIRE, "$source");
    open (ECRIRE, ">$destination");


    while (<LIRE>) {
    my @res = split (/[,()\s]/,$_);

    #Permet d'avoir le nombre d'element du tableau @res
    my $LastElem = $#res;

    #calcul de l'age par rapport à l'année rentrée précédemment
    my $age=$annee-$res[10];

    #ecriture dans le fichier destination
    print ECRIRE "$res[0];$res[2];$res[4];$age;$res[$LastElem]\n";
    }

    il y a quand meme quelque chose que je ne pige pas, par exemple pourquoi $res[10] correspond à l'année dans mon fichier.

    en fait j'aimerais dans la fonction split, supprimer à la fois les virgules, les parentheses les espaces ET les tabulations

    quand je fais dans le script du haut
    print @res j'obtiens la ligne suivante:

    BEAUCHEMINFRANCOISDANAJun41980SorelQCCAN
    mais quand je fais un print $res[6] qui doit correspondre à 1980, j'obtiens alors ANA

    J'ai vraiment des soucis de compréhension dans ces expressions regulieres


    Est-ce que quelqu'un peut m'aider SVP

    merci

  4. #4
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    172
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 172
    Points : 208
    Points
    208
    Par défaut
    Salut,

    vite fait, je n'ai pas le temps maintenant, je verrai ce soir.

    Tu peux faire autre chose.

    Tu peux suprimer les espaces et les tabulations en gardant que le virgules et les paranthèses pour séparation. Dans ce cas ça sera plus simple d'utiliser les indices du tableau.

    lami20j

    P.S. Si tu me donnes le fichier complet ça sera mieux
    --
    lami20j

  5. #5
    Expert confirmé
    Avatar de GLDavid
    Homme Profil pro
    Service Delivery Manager
    Inscrit en
    Janvier 2003
    Messages
    2 852
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Service Delivery Manager
    Secteur : Industrie Pharmaceutique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 2 852
    Points : 4 759
    Points
    4 759
    Par défaut
    osiris73

    les balises codes , s'il te plait !

    @++
    GLDavid
    Consultez la FAQ Perl ainsi que mes cours de Perl.
    N'oubliez pas les balises code ni le tag

    Je ne répond à aucune question technique par MP.

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    172
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 172
    Points : 208
    Points
    208
    Par défaut
    Re,

    toujours vite fait.
    en fait j'aimerais dans la fonction split, supprimer à la fois les virgules, les parentheses les espaces ET les tabulations

    quand je fais dans le script du haut
    print @res j'obtiens la ligne suivante:
    Quand tu fait alors tu auras l'affichage des éléments du tableau comme tu l'as déjà vu sans séparation.

    En revanche si tu fais tu auras les éléments separés par un espace (\n n'as rien à avoir la dédans il est présent seulement pour passer à la nouvelle ligne après l'affichage.

    Tu peux modifier le séparateur par défaut en utilisant la variable $"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    {
      local $" = ";";
      print "@tableau\n";
    }
    En ce cas les éléments seront séparés par ;

    lami20j

    P.S. Il faut lire la documentation pour mieux comprendre
    --
    lami20j

  7. #7
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    Désolé GLDavidpour l'oubli des balises codes

    Merci également à lami20j pour ses différentes réponses.

    Alors j'ai progressé dans mon petit script, je fais maintenant un traitement automatique.

    Je m'explique, j'ai 30 fichiers txt dans un répertoire donné et mon script perl, chaque fichier contient 30 noms, ce qui nous donne donc 900 noms.
    Mon script fonctionne même si je sais qu'il peut y avoir plus propre comme code, bref j'ai quand meme un petit probleme dans la gestion d'erreur du traitement.
    Je m'explique, certaines lignes sont mal formatées, c'est à dire que je peux avoir comme nom "ST. PAUL" du coup quand je calcul l'age de cette personne avec la ligne de code suivante :

    my $age=$annee-$res[10]; j'obtiens le message d'erreur suivant :

    Argument "" isn't numeric in subtraction (-) at D:\TestParLotouFichier.pl line 35, <LIRE> line 34.

    Vu que j'ai 900 lignes, je voudrais savoir sur ligne porte cette erreur et sur quel fichier txt

    je n'arrive pas à faire du traitement d'erreur sous PERL

    voici le script complet

    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
    #!c:\perl\bin\perl.exe -w
        use warnings;use strict;
    
        my @NomFichier;
        my $i=0;
        my $repertoire = ".";
        my @BaseJoueurs;
    
        opendir(DIR, $repertoire) || die "$repertoire: $!";
         @BaseJoueurs = readdir(DIR);
        closedir(DIR);
    
        foreach(@BaseJoueurs) {
         if($_ =~ /.+\.txt/) {
           $NomFichier[$i] = substr($_, 0, - 4);
               $i=$i+1;
            }
        }
    
        for (my $j=0; $j < $i; $j++)
        {
            my $source= "$NomFichier[$j]".".txt";
            my $destinationJoueurs= "./traitement/$NomFichier[$j]"."Joueurs.txt";
           my $destinationGardiens="./traitement/$NomFichier[$j]"."Gardiens.txt";
            open (LIRE, $source) or die "Can't open $source: $!";
         open (ECRIRE1, '>',$destinationJoueurs) or die "Can't open $source: $!";
    open (ECRIRE2, '>',$destinationGardiens) or die "Can't open : $!";
    
        while (<LIRE>)
             {
                my @res = split (/[,()\s]/,$_);
                my $LastElem = $#res;
    # c'est ici que je voudrais lui dire si erreur mais moi dans le fichier err.txt la #ligne où l'erreur c'est produite et dans quel fichier
                my $age=$annee-$res[10]; 
    
                if ($res[4] eq 'G') {
    
    #ecriture dans le fichier gardiens
              print ECRIRE2 "$res[0];$res[2];$res[4];$age;$res[$LastElem]\n";
                    }
    
                else
                     {
    
               print ECRIRE1 "$res[0];$res[2];$res[4];$age;$res[$LastElem]\n";
                    }
            }
        close (ECRIRE2);
        close (ECRIRE1);
        close (LIRE);
    J'espere que j'ai été clair en tout cas merci de votre aide, je continue de chercher de mon coté

    Osiris73

  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
    A vrai dire ici on ne peut pas utiliser les espaces comme séparateur, car il peut y en avoir dans les données à des endroits imprévus, il faut donc combiner un split (pour faire le plus gros du travail) et des regexs pour nettoyer le résultat :
    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
    #!/usr/bin/perl
    #
    use warnings;use strict;
     
    open LIRE,"fichier.txt" or die "E/S : $!\n";
    open ECRIRE, ">","resultat.txt" or die "E/S : $!\n";
     
    while (<LIRE>) {
      my @res = split /[,()]/,$_;
      next unless /^\w/;
      trim(@res[0,1,2,4,6]);
      $res[4] =~ s/(\d+).*/$1/;
      print ECRIRE (join ";",@res[0..2]) . ";${\((localtime)[5]+1900 - $res[4])};$res[6]\n";
    }
     
    sub trim {
      foreach (@_){
        s/^\s*//;
        s/\s*$//;
      }
    }
    Essaie ce code et dis nous ce qu'il en ressort.

    --
    Jedaï

  9. #9
    Membre actif
    Profil pro
    Inscrit en
    Décembre 2005
    Messages
    172
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2005
    Messages : 172
    Points : 208
    Points
    208
    Par défaut
    Salut,
    Citation Envoyé par Jedai
    A vrai dire ici on ne peut pas utiliser les espaces comme séparateur, car il peut y en avoir dans les données à des endroits imprévus,
    En effet. Voilà la raison pour la quelle je n'aime pas trop travailler sur des morceaux des fichiers et ensuite de se rendre compte que ça ne marche pas pour l'ensemble.

    On ne peut pas savoir d'avance toutes les posibilités et personnellemnt je peux pas envisager toutes les posibilités.

    Connaître la structure du fichier entier fait gagner à tout le monde et evite de créer du code inutilisable (j'ai toujours plaisir d'écrire une ligne de code en Perl).

    lami20j
    --
    lami20j

  10. #10
    Candidat au Club
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2005
    Messages : 6
    Points : 3
    Points
    3
    Par défaut
    Merci Jedai de ta réponse

    Alors j'ai copié 6 lignes dans un fichier txt nommé source.txt, j'ai donc executer ton script et j'ai 2 messages d'erreur que voici:

    Use of uninitialized value in substitution (s///) a Test.pl line 18, <LIRE> line 3.
    Use of uninitialized value in substitution (s///) a Test.pl line 18, <LIRE> line 3.

    j'obtiens le fichier resultat.txt qui contient ceci:

    BEECH;KRIS;C;25;CAN
    BIRON;MATHIEU;D;26;CAN
    BOUMEDIENNE;JOSEF;D;28;
    BRADLEY;MATT;R;28;CAN
    CASSELS;ANDREW;C;37;CAN
    CASSIVI;FREDERIC;G;31;CAN

    il manque donc à la ligne 3 la nationnalité du joueur ,
    en fait quand un joueur est né au USA il a une colonne en plus et quand un joueur est né hors USA et CANADA il a une colonne en moins (voir fichier source.txt), j'ai essaye de contourné le probleme en affichant pour la nationalite que la derniere colonne (là ca marche à tous les coups, quelque soit la longueur de la page

    Je mets ici fichier source.txt en piece jointe
    Fichiers attachés Fichiers attachés

  11. #11
    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
    Comme le dit lami20j, il serait nettement préférable de nous fournir des échantillons réels (ou au moins complets si les données sont confidentielles) dès le départ... Ca nous éviterait des tatonnements inutiles !
    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
     
    #!/usr/bin/perl
    #
    use warnings;use strict;
     
    open LIRE,"fichier.txt" or die "E/S : $!\n";
    open ECRIRE, ">","resultat.txt" or die "E/S : $!\n";
     
    while (<LIRE>) {
      my @res = split /[,()]/,$_;
      next unless /^\w/;
      trim(@res[0,1,2,4,-1]);
      $res[4] =~ s/(\d+).*/$1/;
      print ECRIRE (join ";",@res[0..2]),";",(localtime)[5]+1900 - $res[4],";$res[-1]\n";
    }
     
    sub trim {
      foreach (@_){
        s/^\s*//;
        s/\s*$//;
      }
    }
    --
    Jedaï

Discussions similaires

  1. [Débutant] Traitement fichier texte
    Par mathphobic dans le forum MATLAB
    Réponses: 4
    Dernier message: 14/05/2014, 13h29
  2. traitement fichier text
    Par ameno_123 dans le forum Langage
    Réponses: 12
    Dernier message: 17/01/2013, 11h44
  3. Traitement fichier texte
    Par devoluti0n dans le forum Débuter
    Réponses: 21
    Dernier message: 29/09/2007, 13h45
  4. perl doublon fichier texte
    Par falco- dans le forum Langage
    Réponses: 4
    Dernier message: 08/07/2007, 09h12
  5. Traitement fichier texte
    Par spy666ne dans le forum C++
    Réponses: 1
    Dernier message: 30/03/2007, 13h05

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