Problème PERL

Fermé
Navegus - 3 juil. 2009 à 10:15
 Navegus - 8 juil. 2009 à 11:25
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!
A voir également:

16 réponses

lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
3 juil. 2009 à 10:42
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
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
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
3 juil. 2009 à 11:21
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
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

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
3 juil. 2009 à 14:12
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
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
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
3 juil. 2009 à 15:56
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
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
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 juil. 2009 à 11:13
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
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
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 juil. 2009 à 11:58
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
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
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 juil. 2009 à 14:47
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
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 juil. 2009 à 19:03
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
lami20j Messages postés 21331 Date d'inscription jeudi 4 novembre 2004 Statut Modérateur, Contributeur sécurité Dernière intervention 30 octobre 2019 3 569
6 juil. 2009 à 19:11
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
Merci, ça fonctionne!
0