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 :

Récupération données dans un fichier texte


Sujet :

Langage Perl

  1. #1
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 92
    Points : 61
    Points
    61
    Par défaut Récupération données dans un fichier texte
    Bonjour,

    je suis novice en perl et je veux traiter un fichier texte ci -joint qui a des données(données espacées) en perl 5.10 comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    0AC@21XAA          A NAAA_001 MARRT     AC@21XAA         NERP_111 MARRT
    Je veux récupérer dans chaque ligne,chacune des données et separer par un diese"#" et mettrer null la où la donnée est vide.

    Ensuite le mettre dans un autre fichier.

    Avez-vous une idée ?

  2. #2
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 848
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 848
    Points : 6 535
    Points
    6 535
    Par défaut
    Montre nous ce que tu as déjà fait.
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  3. #3
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 92
    Points : 61
    Points
    61
    Par défaut
    Bonjour @CosmoKnacki

    voici ce que j'ai déjà fait, du coup ça ne correspond pas encore à ce que j'attends.
    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
     
     
    use warnings; 
     
    # my $var1 = ""; 
     
    #print "Début du traitement" 
     
    #  test des paramètres
     
       if ($ARGV[0] eq "") {
            print " syntaxe : perl numerote.pl nom_de_fichier \n" ;
            exit(-1) ;
       }  ; # fin de test sur les arguments
     
       $fichier_in = $ARGV[0] ; # récupération du nom du fichier
     
    #lire dans monfichier.txt 
    open (FIC,"<$fichier_in") or die "\n impossible d'ouvrir le fichier nommé $fichier_in \n\n" ;
    #écrire dans mon test.txt
    open (ECRIRE,">result.txt") or die "\n Erreur de creation du fichier \n\n" ; 
     
    #tant qu'il y a des lignes dans mon fichier
    while (my $ligne = <FIC>)
    { 
     
     
        if ($ligne =~ /^\w+\s+\s+/ )
        { 
                $ligne=~ s/.*(^\w+\s+\s+).*/$1/;
         print "Mot  : $ligne \n"; 
        } 
        print ECRIRE $ligne;
     
     
     
    }
     
    #fermeture des fichiers
    close FIC; 
    close ECRIRE; 
    #print "Fin du traitement"
    #print ECRIRE $ligne;

  4. #4
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 848
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 848
    Points : 6 535
    Points
    6 535
    Par défaut
    Ok, le premier objectif est de récupérer chaque champ; une des difficultés se trouve dans l'écriture de la pattern étant donné que certaine lignes se terminent avant le dernier champ (sans espaces pour combler).
    Comme tu as dis dans ton premier post qu'il s'agissait de données espacées, il faut donc construire une pattern qui capture les champs et qui décrivent les espaces entre eux. À regarder le fichier example-data.txt, j'en ai déduit que les lignes avaient une longueur maximum de 110 caractères (sans compter le LF). Donc mon idée pour simplifier l'écriture de la pattern est de combler toute ligne de moins de 110 caractères avec des espaces. De cette manière, il n'est plus utile de vérifier si tel ou tel groupe existe en fin de ligne pour écrire la pattern.
    Cette pattern est (si je ne me suis pas planté):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my $reg = qr/^(.{9}) {10}(.) (.{8}) (.{5}) {5}(.{8}) {9}(.{8}) (.{5}) {6}(.) (.{8}) {9}(.{8}) (.{5})/;
    Ça fait donc 11 champs (donc 11 groupes de capture) séparés par un nombre variable d'espaces. Est-ce que tu confirmes ou est-ce que tu vois le découpage d'une autre manière (difficile de savoir si le A isolé fait partie du champ suivant ou si c'est un champ à part entière)?

    Une fois raccord la dessus, la suite est relativement simple:
    • On créé une chaîne formatée (pour sprintf) qui permet de justifier chaque placeholder.
    • On passe en revue chaque champs pour voir ceux qui sont uniquement remplis d'espaces, puis dans ce cas on les remplace par #.
    • Plus qu'à enregistrer la ligne générée avec les champs et la chaîne formatée dans le fichier de sortie.


    Au passage, ça c'est un peu trop old school:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    open (FIC,"<$fichier_in")
    Désormais on utilise open avec 3 arguments et le filehandler est une vraie variable:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    open(my $fhi, '<', $fichier_in)
    Autre chose, démarre ton script avec: use strict;.

    Perl 5.10 date de 2007, une petite mise à jour peut-être?
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  5. #5
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 92
    Points : 61
    Points
    61
    Par défaut
    Ok merci CosmoKnacki


    quelques précisions :

    - Je confirme 11 groupes à capturer (voir screen shoot)
    - le "A" est bien un groupe à capturer
    - Et si tu regardes bien, les 2 premières lignes concernent l'élément 0AC@21XAA
    - les lignes 3 et 4 concernent l'élément 0AC@31XAA

    l'expression regulière ne matche pas la 1 ,3 et 5.Mais matche les autres.

    Au passage,peux tu l'expliquer cette regex ?

    Donc il faut que j'arriver à le montrer lors de la recup de mes donnees.

    Autres choses :
    cette partie que tu as dit :
    On créé une chaîne formatée (pour sprintf) qui permet de justifier chaque placeholder.
    On passe en revue chaque champs pour voir ceux qui sont uniquement remplis d'espaces, puis dans ce cas on les remplace par #.
    Plus qu'à enregistrer la ligne générée avec les champs et la chaîne formatée dans le fichier de sortie.
    je le vois comme ça, pas trop sûr
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
     
    while (my $ligne = <FIC>)
    { 
     
    my $reg = qr/^(.{9}) {10}(.) (.{8}) (.{5}) {5}(.{8}) {9}(.{8}) (.{5}) {6}(.) (.{8}) {9}(.{8}) (.{5})/;
     if ($ligne =~$reg )
        { 
                $ligne=~$reg/$1/;
         print "$ligne# \n"; 
        } 
        print ECRIRE $ligne;
     
    }
    qu'en dis-tu ?

  6. #6
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 848
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 848
    Points : 6 535
    Points
    6 535
    Par défaut
    Alors concernant la regex et les lignes qu'elle ne matche pas, je l'ai expliqué précédemment, c'est dû au fait que certaines lignes (la 1, la 3, etc.) sont plus courtes, c'est pourquoi il faut ajouter des espaces à ces lignes (pour atteindre les 110 caractères) afin que la pattern réussisse. Cette pattern est certes un peu longue mais en revanche très simple, donc si tu veux en percer les mystères un tutoriel de base fera l'affaire. Le but de cette pattern est d'obtenir un tableau avec chaque champ.

    Pour ce qui est de la chaîne formatée, je me suis trompé, on en a pas besoin pour le résultat que tu souhaites obtenir. Il suffit à la place de joindre les champs avec #.

    Voici une démo sans 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
    use strict;
    use warnings;
     
    my $reg = qr/^(.{9}) {10}(.) (.{8}) (.{5}) {5}(.{8}) {9}(.{8}) (.{5}) {6}(.) (.{8}) {9}(.{8}) (.{5})/;
     
    while (my $line = <DATA>) {
        # on enlève le caractère \n en fin de ligne
        chomp($line);
        # on ajoute une centaine d'espaces pour être sûr que la pattern réussisse
        $line .= ' ' x 100;
     
        # on applique la regex pour récupérer les 11 champs
        my @fields = ($line =~ $reg);
     
        # on remplace les champs vides par null
        @fields = map { s/^ *$/null/r } @fields;
     
        $line = join('#', @fields) . "\n";
     
        print $line;
     
    }
     
    __DATA__
    0AC@21XAA          A NAAA_001 MARRT     AC@21XAA         NERP_111 MARRT     
                         NBBB_250 MARRT                                          A AC@21XAA         NREP_001 MARRT
    0AC@31XAA          A NCCC_001 MARRT     AC@31XAA         NERP_111 MARRT
                         NEEE_250 MARRT                                          A AC@31XAA         NREP_001 MARRT
    0ACACAJAA          A NFFF_001 MARRT     ACACAJAA         NERP_111 MARRT
                         NLLL_250 MARRT                                          A ACACAJAA         NREP_001 MARRT
                                                                                 A ACAC8JAA         NREP_001 MARRT
                                                                                 A ACW40JAA         NREP_001 MARRT
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  7. #7
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 92
    Points : 61
    Points
    61
    Par défaut
    Bonjour @CosmoKnacki
    voici mon 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
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
     
    #use strict;
    use warnings;
     
    $fichier = $ARGV[0] ; # récupération du nom du fichier
     
    my $reg = qr/^(.{9}) {10}(.) (.{8}) (.{5}) {5}(.{8}) {9}(.{8}) (.{5}) {6}(.) (.{8}) {9}(.{8}) (.{5})/;
     
    #lire dans monfichier.txt 
    open (FIC,"<$fichier") or die "\n impossible d'ouvrir le fichier nommé $fichier \n\n" ;
    #écrire dans mon test.txt
    open (ECRIRE,">result.txt") or die "\n Erreur de creation du fichier \n\n" ; 
     
     
    while (my $line = <FIC>) {
        # on enlève le caractère \n en fin de ligne
        chomp($line);
        # on ajoute une centaine d'espaces pour être sûr que la pattern réussisse
        $line .= ' ' x 100;
     
        # on applique la regex pour récupérer les 11 champs
        my @fields = ($line =~ $reg);
     
        # on remplace les champs vides par null
        @fields = map { s/^ *$/null/r } @fields;
     
        $line = join('#', @fields) . "\n";
     
        print ECRIRE $line;
    }
     
    #fermeture des fichiers
    close FIC; 
    close ECRIRE;
    j'ai une erreur de compilation à cette ligne @fields = map { s/^ *$/null/r } @fields;
    voici l'erreur :
    Bareword found where operator expected at extract.pl line 24, near "s/^ *$/null/r"
    Unquoted string "r" may clash with future reserved word at extract.pl line 24.
    syntax error at extract.pl line 24, near "s/^ *$/null/r "
    Execution of extract.pl aborted due to compilation errors.

  8. #8
    Expert éminent Avatar de CosmoKnacki
    Homme Profil pro
    Justicier interdimensionnel
    Inscrit en
    Mars 2009
    Messages
    2 848
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Justicier interdimensionnel

    Informations forums :
    Inscription : Mars 2009
    Messages : 2 848
    Points : 6 535
    Points
    6 535
    Par défaut
    Comme je l'ai dit dans un précédent post Perl 5.10 c'est pas tout jeune, donc je suppose qu'il ne connaît pas le modificateur r qui permet de renvoyer la chaîne substituée (la chaîne après transformation) plutôt que le résultat de la substitution (1).

    Tu peux le remplacer en faisant ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    @fields = map { s/^ *$/null/; $_ } @fields;
    Brachygobius xanthozonus
    Ctenobrycon Gymnocorymbus

  9. #9
    Membre du Club
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juin 2012
    Messages
    92
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2012
    Messages : 92
    Points : 61
    Points
    61
    Par défaut
    cool, là ça marche.
    un grand merci

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

Discussions similaires

  1. [VBA-E]Ecriture de données dans un fichier texte
    Par osito57 dans le forum Macros et VBA Excel
    Réponses: 15
    Dernier message: 18/08/2017, 20h42
  2. Réponses: 2
    Dernier message: 03/07/2012, 15h48
  3. récupération de données dans un fichier texte
    Par capucine1983 dans le forum Langage
    Réponses: 4
    Dernier message: 30/06/2007, 01h16
  4. Réponses: 2
    Dernier message: 16/01/2006, 20h34
  5. Réponses: 3
    Dernier message: 22/02/2004, 21h09

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