Problème PERL

Navegus -  
 Navegus -
Bonjour,

Etand débutant en perl, je me retrouve confronté à un problème:
Je possède un certain nombre de fichiers dans lesquels se trouve à chaque fois une liste défini par le modèle suivant:

p_a = 1
p_b = 2
p_c = 3
p_d = 4 ...

Je souhaiterai extraire ce qui se trouve après le signe égal pour pouvoir stocker la valeur dans des variables tels que $a, $b, $c etc.. afin de pouvoir réaliser des calculs ultérieurement avec ces valeurs

Merci d'avance pour votre aide!
Configuration: Windows XP Internet Explorer 6.0

16 réponses

  1. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    Je pense que le stockage doit être fait plutôt dans un tableau.
    @ARGV = ( "fichier1.txt", "fichier2.txt",..............., "fichierN.txt");
    
    while (<>){
      next unless /.*=\s*(\d+)/;
      push @tab,$1;
    }
    0
  2. Navegus
     
    Merci pour cette réponse rapide!

    Cependant un détail que je n'ai pas mentionné est que la partie avant les underscore dépend du fichier dans lequel je me trouve et ce qui se trouve après l'underscore est commune à tous mes fichiers. (dans la liste!)
    De plus il y a des élements dans mon fichier avant, après et même à coté de cette liste.

    Que faire? Le tableau est il une solution efficace quand même?

    Merci d'avance
    0
  3. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    Les détails sont toujours importants ;-)
    De toute façon des variables individuelles ce n'est pas très pratique, vu que tu dois avoir plusieurs fichiers et données.

    je n'ai pas mentionné est que la partie avant les underscore dépend du fichier dans lequel je me trouve

    En ce cas je pense que le bonne solution sera les hash.
    Mais en ce cas j'ai besoin de savoir avec précision ce que tu veux faire (de début à la fin y compris les calculs qui suivent après le stockage).
    Une solution générique ne sera pas fiable.
    0
  4. Navegus
     
    Je ne peux pas te fournir avec precision ce que je veux faire vu que je travaille avec des données confidentielles mais je peux te donner quelquechose qui s'en rapproche:

    Tous mes fichiers se présentent de la manière suivante:

    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    **************************************
    ***************
    + fichier1_longueur = 1 // Ceci est un commentaire
    + fichier1_largeur = 2 // Ceci est un commentaire
    + fichier1_surface = 3 // Ceci est un commentaire
    + fichier1_param1 = 4 // Ceci est un commentaire
    + fichier1_param2 = 5 // Ceci est un commentaire
    + fichier1_param3 = 6 // Ceci est un commentaire
    + fichier1_param4 = 7 // Ceci est un commentaire
    + fichier1_param5 = 8 // Ceci est un commentaire
    + fichier1_param6 = 9 // Ceci est un commentaire
    + fichier1_param7 = 10 // Ceci est un commentaire
    + fichier1_param8 = 11 // Ceci est un commentaire
    + fichier1_param9 = 12 // Ceci est un commentaire
    + fichier1_param10 = 13 // Ceci est un commentaire
    ....
    ... (ainsi de suite jusqu'a)
    ++ fichier1_param27 = 14 // Ceci est un commentaire

    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    *Ceci est du commentaire
    __________________________________________________________________________________________

    Ce que je voudrai faire est un programme qui suivant le choix de l'utilisateur extrait du fichier adéquat les paramètres et renvoie d'autres paramètres issus de calcul à partir des paramètres extraits!
    (Les calculs sont des calcus simples addition, multiplication etc...)

    Merci d'avance!
    0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    qui suivant le choix de l'utilisateur
    Quels choix peut faire l'utilisateur et quel utilisateur?

    extrait du fichier adéquat les paramètres
    Tu parles de (voir en gras) ça par exemple?
    + fichier1_longueur = 1 // Ceci est un commentaire
    C'est ça que tu appelles paramètre extrait?!

    et renvoie d'autres paramètres issus de calcul à partir des paramètres extraits!
    Renvoi où, pourquoi et comment?!

    Tu dois avoir plusieurs fichiers donc une seule lecture est faisable.
    Le nom de fichier (je suppose que est unique) pourra être utilisé pour la clé de hash.
    Ensuite les valeurs seront stocké dans un tableau anonyme, bref ça sera un hash de tableaux.

    J'aurai besoin que tu me dises ce que tu veux obtenir.
    Donc en partant de deux fichiers, montre ce que tu veux avoir comme résultat. N'oublie pas d'expliquer que veut tu dire par choix utilisateur

    fichier1
    *Ceci est du commentaire 
    ************************************** 
    *************** 
    + fichier1_longueur = 1 // Ceci est un commentaire 
    + fichier1_largeur = 2 // Ceci est un commentaire 
    
    *Ceci est du commentaire 
    fichier2
    *Ceci est du commentaire 
    ************************************** 
    *************** 
    + fichier2_longueur = 10 // Ceci est un commentaire 
    + fichier2_largeur = 20 // Ceci est un commentaire 
    
    *Ceci est du commentaire 
    0
  7. Navegus
     
    Pour le moment je ne travaillle qu'avec la console linux!
    J'entends par utilisateur tout simplement celui qui utilise le programme et qui interagit avec la console

    Considérons le cas de deux fichiers:

    Au depart, on propose deux choix à l'utilisateur:
    Choix 1 et Choix2
    Si l'utilisateur tape 1, je dois aller dans le fichier 1 extraire longueur=1 et largeur= 2 et lui renvoyer (par exemple) surface = longueur*largeur=2
    Idem si son choix est le numero 2
    0
  8. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    Le nom de fichiers est important en ce cas.
    Si les fichiers ont le nom de genre :
    nomfichier1
    nomfichier2
    .....

    on n'a pas besoin d'un menu avec plusieurs choix il suffit de demander le numéro de fichier
    vu que un fichier est traiter à la fois alors underscore ne nous interesse pas
    #!/usr/bin/perl
    use strict;use warnings;
    
    my @parametre;
    
    printf "Entrez le numéro de fichier [ 1 à 10] : \n";
    chomp(my $n = <STDIN>);
    
    open FICHIER, "/chemin/absolu/vers/nomfichier$n"
      or die "E/S : $!\n";
    
    while (<FICHIER>){
       next unless /.*=\s*(\d+)/;
       push @parametre,$1; # les éléments de tableau sont les paramètre de 1 à 14
    }
    
    close FICHIER;
    __END__

    P.S.
    C'est difficile de donner une solution quand on n' a pas tous les éléments ;-(
    0
  9. Navegus
     
    Merci de ton aide lami20j, mais j'ai encore quelques soucis:

    Mes paramètres sont en notation scientifique tel que 1.22225e-6. Or je n'arrive qu'à extraire le chiffre des unités alors que je voudrai le reste aussi!

    Par ailleurs, question subsidiaire: existe-il une fonction permettant de n'extraire que la ligne de la première occurence d'un mot et non pas toutes les lignes où apparaissent ce mot?
    Je sais que la commenade linux est grep mot fichier |head -1, mais je n'arrive pas à le transcrire en perl...

    Merci bien!
    0
  10. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Salut,

    Voici un exemple (je n'ai pas testé).

    Mets ça dans un fichier et exécute le pour voir si ça marche.
    #!/usr/bin/perl
    use strict;use warnings;
    
    my $h;
    while(<DATA>){
      s/^(\w+)/
      next if $h{$1};
      print "ligne $. $_";
    }
    __END__
    mot1 1ère occurence
    mot2 1ère occurence
    mot1 2ème occurence
    mot3 1ère occurence
    mot2 2ème occurence
    mot1 3ème occurence
    mot3 2èmeoccurence
    0
  11. Navegus
     
    Juste pour revenir au message 7, je n'arrive qu,à extraire pour le moment que le premier chiffre de mes paramètres comment pourrais-je faire pour extraire complètement mon paramètre de la forme 1.23456e-6 par exemple?

    Merci
    0
  12. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    Mets au lieu de
    next unless /.*=\s*(\d+)/;

    ça
    next unless /.*=\s*(([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?)/

    si jamais après égal tu n'as qu'espace suivi de nombre alors tu peux écrire tout simplement
    next unless /.*=\s*(.*)/;
    0
  13. Navegus
     
    Merci Ca fonctionne! Mais si tu as le temps pourrais tu m'expliquer la regExp :

    next unless /.*=\s*(([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?)/


    Histoire de ne pas recopier bêtement...
    0
  14. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,
    ([+-]?) # on prends en compte la posibilité
            # d'avoir un signe + ou - 
    	# le ? c'est le quantificateur pour facultatif
    	# donc soit + soit - soit rien
    
    (?=\d|\.\d) # on traite les nombres qui commencent avec
                # soit un chiffre
                # soit un point décimal suivi d'un chiffre
    	    # c'est un test avant vu (?=
    		 
    \d* # n'importe combien des chiffres zéro, une ou plusieurs
    
    (\.\d*)? # on s'assure de l'existance de point décimal suivi de chiffres
             # si le point à été consommé par le test avant 
             # le quantificateur facultatif ? 
    	 # permet de ne pas traiter cette partie
    
    (
    [Ee]       # on ne sait pas si c'est E ou e dans la notation
    ([+-]?\d+) # on prends en compte les cas E+N, e+N, E-N, e-N, EN, eN (N de 0 à 9)
    )?         # tout ça facultatif ce qui permet de reconnaître par exemple 1.25

    Et pour le message 9 ?!
    0
  15. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    J'ai fait pas mal des erreurs dans le message 9 ;-))
    Voici une version qui fonctionne
    lami20j@debian:~/trash/ccm_perl$ cat occurence.pl
    #!/usr/bin/perl
    use strict;use warnings;
    
    my %h;
    while(<DATA>){
      /^(\w+)/;
      push @{$h{$1}},$_;
    }
    
    print "$h{$_}[0]" for (sort keys %h);
    
    __END__
    mot1 1ère occurence
    mot2 1ère occurence
    mot1 2ème occurence
    mot3 1ère occurence
    mot2 2ème occurence
    mot1 3ème occurence
    mot3 2ème occurence
    lami20j@debian:~/trash/ccm_perl$ perl occurence.pl
    mot1 1ère occurence
    mot2 1ère occurence
    mot3 1ère occurence
    
    0
  16. lami20j Messages postés 21506 Date d'inscription   Statut Modérateur, Contributeur sécurité Dernière intervention   3 571
     
    Re,

    Version améliorée, on stocke seulement la 1ère occurence
    #!/usr/bin/perl
    use strict;use warnings;
    
    my %h;
    while(<DATA>){
      /^(\w+)/;
      push @{$h{$1}},$_ unless $h{$1};
    }
    
    
    print "$h{$_}[0]" for (sort keys %h);
    
    __END__
    mot1 1ère occurence
    mot2 1ère occurence
    mot1 2ème occurence
    mot3 1ère occurence
    mot2 2ème occurence
    mot1 3ème occurence
    mot3 2ème occurence
    
    
    0