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 et la manipulation des fichier text


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 37
    Points : 22
    Points
    22
    Par défaut perl et la manipulation des fichier text
    Bonjour,

    je suis debutante en perl et je sollicite votre aide! mon probleme ests le suivant:

    je desire analyser un tres grand fichier text et voici un extrait:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    [3] est la quantite du legume : tomate
    il ya des tomates des navets et pas de carottes
    [4] est la quantite du legume : navet
    [6] est la quantite du legume : chou
    ggggggggggggggjlkjdshryzy
    [9] est la quantite du fruit : orange
    [8] est la quantite du fruit : banane
    il ya pas de fraise 
    [5] est la quantite du fruit : pomme
    pas de pain de compagne
    [13] est la quantite du pain : croissant
    gfjgdsfgjgdjfhgdjhgfjhdsgfjhqgdhjfg
    [3] est la quantite du pain : pain au chocolat
    et je desire savoir les produits presents dans la dans le fichier alors il faudrait que j'aurais le resulta suivant: legume, fruit et pain

    j'ai le script suivant mais il affiche toutes les les ligne qui ont le format de l'expression regulier alors que c pas ce qui est demandé
    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
    #!/usr/bin/perl
     
    open FILE, "hh.txt";
     
     
    while ($line=<FILE>){
    	if ($line=~/\[(.*)\] (.*) quantite du (.*)/) {
     
     
                 print "$line";
     
    	 }
     
    }
     
    close FILE;
    pourriez-vous m'aimer a debloquer ce bug?

    je vous remercie a l'avance

  2. #2
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Tu devrais lui faire afficher ta troisième capture ($3) au lieu de la ligne $line. Tu peux aussi simplifier (et raffiner) ta regex.

    Voilà un exemple (qui en fait un peu plus, en matière de capture et d'affichage), qui devrait te permettre de progresser.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    my %products;
    while (<FILE>) {
        $products{$2} += $1 if (/\^[(\d+)\].*: ([\w| ]*)$/);
    }
    print map {"$_ $products{$_}\n"} sort keys %products;
    La capture est à la fois plus simple (je prends que ce dont j'ai besoin) et plus précise (j'en dis plus sur où il faut prendre).

    Rappel :
    ^ et $ sont les ancres de début et de fin de chaîne. La précision permet d'éviter les lignes qui ne comment pas par [\d+].

    \d pour chiffre, \w pour alphanumérique et | alternative
    L'utilisation d'un tableau associatif (hash) te permets de compter les éléments (tu n'es pas obligé!), tout en stockant le nom des produits. Clé du hash = nom et valeur du hash = nombre (avec incrémentation si déjà présent).

    le map {} prend une liste en entrée (liste des clés du hash) et recrache une liste de chaînes (en l'occurence la clé et sa valeur) à print.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 37
    Points : 22
    Points
    22
    Par défaut
    merci pour votre reponse .

    mon probleme est un peu complexe car apres je vais m'enservire du resultat de ce fichier par la suite dans autre chose,

    j'ai modifié le scrip comme suit :
    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
    #!/usr/bin/perl
     
    open FILE, "hh.txt";
     
     
    while ($line=<FILE>){
     
    	if ($line=~/\[(.*)\] (.*) quantite du (.*) :(.*)/) {
     
     
                 print "$3\n";
     
    	 }
     
    }
     
    close FILE;
    et j'aurai le resultat suivant:
    legume
    legume
    legume
    fruit
    fruit
    fruit
    pain
    pain

    mais moi je veux just avoir le resultat suivant:
    legume
    fruit
    pain

    merci pour votre reponse

  4. #4
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 37
    Points : 22
    Points
    22
    Par défaut
    je pense que il faudrait que je compare l'element $3 avec les element du tableau s'il il n'existe pas dans le tableau alors je l'ajoute mais sinon si il existe je l'ajoute pas pas au tableau et vers la fin j'affiche ce tableau !! je pense que c'est ça la solution.

    mais le probleme je manipule pas bien les tableau .

    Pourrier vous m'aider SVP

    merci d'avance;

  5. #5
    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 linda8080 Voir le message
    je pense que il faudrait que je compare l'element $3 avec les element du tableau s'il il n'existe pas dans le tableau alors je l'ajoute mais sinon si il existe je l'ajoute pas pas au tableau et vers la fin j'affiche ce tableau !! je pense que c'est ça la solution.
    En fait il y a plus simple : il suffit d'utiliser un hash. Dans un hash, les clés sont uniques, donc même si tu rajoutes plusieurs fois la même clé, il n'y aura toujours qu'une seule clé avec cette dénomination.

    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
    #!/usr/bin/perl
    use strict; use warnings;
     
    my $filename = 'hh.txt';
    open my($file), '<', $filename
      or die "N'a pas pu ouvrir $filename : $!\n";
     
    my %products;
    while (my $line = <$file>){
       if ($line =~ m/^\s*\[(\d+)\] [^d]* du (\w+) :/) {
          $products{$2} += $1;
       }
    }
     
    print join "\n", sort keys %products;
     
    __END__
    --
    Jedaï

  6. #6
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    En fait il y a plus simple : il suffit d'utiliser un hash. Dans un hash, les clés sont uniques, donc même si tu rajoutes plusieurs fois la même clé, il n'y aura toujours qu'une seule clé avec cette dénomination.
    Si tu avais lu, ou simplement exécuté le code que je t'ai proposé, tu aurais réalisé par toi-même ce que te dis Jedaï.

    Car le code fait exactement cela. Bien sûr tu peux ne pas afficher le nombre d'occurrence.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print map {"$_\n"} sort keys %products;
    De plus si tu n'as vraiment que faire du nombre de produits, tu peux aussi ne pas les capturer et ne pas les stocker dans le hash.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $products{$1} = 1 if (/^\[\d+\].*: ([\w| ]*)$/);
    (La regex de Jedaï est — bien entendu — encore plus précise)

    Je t'avais proposé l'exemple non pas pour que tu aies du prêt à emporter mais pour t'aider à comprendre comment faire.

    Ah oui, si tu veux préserver l'ordre dand lequels les produits sont rencontrés, empilent les dans une liste à la première occurrence (là encore le hash t'est utile).

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 37
    Points : 22
    Points
    22
    Par défaut
    je comprends pas cette ligne de code , pourriez vous me l'expliquer SVP


  8. #8
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Rappel (au cas où) : un hash (ou tableau associatif) est une liste de clé et de valeur. A chaque clé est associée une valeur.

    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    my %products;
    $products{pomme} = 10;
    $products{orange} = 2;
     
    # ou encore, déclaration directe
     
    my %sites = {
        'http://www.perlmonks.org/' => 'perl',
        'http://www.mongueurs.net/' => 'perl',
        'http://www.haskell.org/' => 'haskell'
    }
    Dans :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $products{$2} += $1 if (/\^[(\d+)\].*: ([\w| ]*)$/);
    $1 et $2 sont la 1ere et la 2eme capture dans la regex (qui valent donc 3 et tomate à la lecture de la première ligne). $products{$2} += $1 incrémente de $1 ( = le nbre d'unité) la valeur de $2 (= le nom du produit) dans la tableau associatif %products. Dans le cas de la première ligne $products{$2} += $1 vaut $products{tomate} += 3 et donc incrémente 3 à $products{tomate}.

  9. #9
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 37
    Points : 22
    Points
    22
    Par défaut
    je prefere utiliser les tableaux car il faut que je garde l'ordre des éléments dans lequel ils apparaissent et ensuite je vais les passer comme arguments à une autre fonction .

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 37
    Points : 22
    Points
    22
    Par défaut
    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
    [21221]ggggggggggggggggggggggggg tcp uid = 8471
    [21221]ggggggggggggggggggggggggg tcp uid = 8471
    [21221]ggggggggggggggggggggggggg tcp uid = 471
    [21221]ggggggggggggggggggggggggg tcp uid = 2071
    [21221]ggggggggggggggggggggggggg tcp uid = 8971
    [21221]ggggggggggggggggggggggggg tcp uid = 871
    [21221]ggggggggggggggggggggggggg tcp uid = 71
    [21221]ggggggggggggggggggggggggg tcp uid = 80
    tyyyyyyyyyyyyyyyyyyy tcp 2343
    [45125]rrrrrrrrrrrrrrrrrrrr tcp uid = 8073
    yuyyuidshfhhfhfjfjjf tcp uid 45654
    [214522] ssssssssssssssssssssssssssss ack uid = 8074
    [23456] gdgsfdgshjufuioufoaiuoifuaoiueio tcp  uid = 435
    [12.310272]le (node 0) va envoyer  le paquet  pkt: type = tcp,a la couche physique qui a identificateur  uid = 807  
    [12.314208]le (node 1) viens de recevoir le paquet  pkt: type = tcp de la couche haute  uid = 807 
    [12.314432]le (node 1) va envoyer  le paquet  pkt: type = M_ACK,a la couche physique qui a identificateur  uid = 807  
    [12.314784]le (node 0) viens de recevoir le paquet  pkt: type = M_ACK de la couche haute  uid = 807 
    [12.314784]le (node 0) viens de recevoir le paquet  pkt: type = tcp de la couche haute  uid = 809
    et voici mon code qui ne marche pas encore !
    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
    #!/usr/bin/perl
     
    open FILE, "test.txt";
    $i=0;
    @tab=();
    while ($line=<FILE>){
    	if ($line=~/\[(.*)\](.*)tcp (.*)uid = (.*)/) {
    if ($i=0){ 
          $tab[0]=$4;
          $i=$i+1;
    }
    elsif($tab[$#tab]=$4){
           $tab[$#tab+1]=$4;
          $i=$i+1;
     
            }
     
    }
    }
     if (@tab){
    print ("@tab \n");
    }	
    close FILE;
    Merci pour votre reponse

  11. #11
    Membre à l'essai
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 37
    Points : 22
    Points
    22
    Par défaut
    je debute avec perl et je ne manipule pas bien les tableau et les hach mais j'aimerai avoir les identificateur pour les passer apres comme argument a une autre fonction

  12. #12
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Bonsoir.

    Si tu veux simplement la liste des valeurs numériques en fin de ligne et que peu t'importent les autres informations alors fais plutôt comme suit:
    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 strict; 
    use warnings;
     
    open my $fh, '<', 'test.txt';
     
    my @list;
    while(<$fh>) {
        push @list, $1 if /\s+(\d+)$/;
    }
     
    print map {$_, "\n"} @list;
    PS Tu n'utilises ni use strict; ni use warnings; c'est une très mauvaise idée, tu as peu de chance d'avoir des scripts qui fonctionnent.

Discussions similaires

  1. Manipulation des fichiers textes sous DELPHI
    Par riad.yahiaoui dans le forum Débuter
    Réponses: 9
    Dernier message: 24/04/2014, 16h47
  2. Manipuler des fichiers Excel avec Perl
    Par Buboba dans le forum Modules
    Réponses: 2
    Dernier message: 04/09/2012, 13h54
  3. Manipulation des fichiers textes
    Par tickerdu22 dans le forum C#
    Réponses: 1
    Dernier message: 17/02/2008, 19h45
  4. Réponses: 2
    Dernier message: 07/10/2007, 19h52
  5. Réponses: 3
    Dernier message: 24/05/2007, 10h21

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