Langage perl
Fermé
ba_na
Messages postés
1
Date d'inscription
mardi 18 juin 2013
Statut
Membre
Dernière intervention
20 juin 2013
-
20 juin 2013 à 08:30
na_ba85 Messages postés 8 Date d'inscription mardi 18 juin 2013 Statut Membre Dernière intervention 1 septembre 2017 - 24 juin 2013 à 22:57
na_ba85 Messages postés 8 Date d'inscription mardi 18 juin 2013 Statut Membre Dernière intervention 1 septembre 2017 - 24 juin 2013 à 22:57
A voir également:
- Langage perl
- Langage ascii - Guide
- Débuter langage batch windows - Guide
- Denon perl pro test - Guide
- Langage binaire - Guide
- Puissance en langage c ✓ - Forum C
2 réponses
[Dal]
Messages postés
6174
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
2 février 2024
1 083
20 juin 2013 à 10:17
20 juin 2013 à 10:17
Salut naba,
De quel type d'aide as-tu besoin ? Tes indications sont un peu courtes :-)
Dal
De quel type d'aide as-tu besoin ? Tes indications sont un peu courtes :-)
Dal
na_ba85
Messages postés
8
Date d'inscription
mardi 18 juin 2013
Statut
Membre
Dernière intervention
1 septembre 2017
20 juin 2013 à 14:17
20 juin 2013 à 14:17
Bonjour Dal,
Tout d'abord merci pour ta reponse et conseil.
Voici mon script avec les infos où je bloque :
# But : De chercher les mots suivants (mot1, mot2, mot3, mot4) dans le fichier.txt.
# A chaque mot trouvé, ça me renvoi Ok et passe au suivant et ainsi de siute
# Si un mot n'est pas present, il me renvoi KO
# Déclarations de mes variables
my $fic_log_uc = "......./fichier.txt";
my ($valeur1,$mot1);
my ($valeur2,$mot2);
my $status = 'KO';
# Main
open (LIRE_LOG, '<', $fic_log) or die "Impossible d'acceder au fichier";
while (<LIRE_LOG>)
{
# Appel de ma fonction
main->check;
}
print LOG "$mot1;$mot2;$status\n";
close (LOG);
close (LIRE_LOG);
# Functions
sub check
{
if ($_ =~ /mot1/)
{
#print "$_\n";
($valeur1,$mot1) = split(/=/,$_);
$mot1=~ s/\r//;
chomp($mot1);
$status = "OK";
}
if ($_ =~ /mot2/)
{
#print "$_\n";
($valeur2,$mot2) = split(/=/,$_);
$mot2=~ s/\r//;
chomp($mot2);
$status = "OK";
}
if ($_ =~ /mot3/)
{
#print "$_\n";
$status = "OK";
}
if ($_ =~ /mot4/)
{
#print "$_\n";
$status = "OK";
}
elsif ($status eq "KO")
{
$mot1 = "inexistant";
$mot2 = "inexistant";
$status = "KO";
#print "$status\n";
}
return $mot1;
return $mot2;
return $status;
}
# Mon script ne marche pas car le mot4 n'est pas present dans mon fichier, il me renvoi comme même OK :(
Merci pour votre aide
Tout d'abord merci pour ta reponse et conseil.
Voici mon script avec les infos où je bloque :
# But : De chercher les mots suivants (mot1, mot2, mot3, mot4) dans le fichier.txt.
# A chaque mot trouvé, ça me renvoi Ok et passe au suivant et ainsi de siute
# Si un mot n'est pas present, il me renvoi KO
# Déclarations de mes variables
my $fic_log_uc = "......./fichier.txt";
my ($valeur1,$mot1);
my ($valeur2,$mot2);
my $status = 'KO';
# Main
open (LIRE_LOG, '<', $fic_log) or die "Impossible d'acceder au fichier";
while (<LIRE_LOG>)
{
# Appel de ma fonction
main->check;
}
print LOG "$mot1;$mot2;$status\n";
close (LOG);
close (LIRE_LOG);
# Functions
sub check
{
if ($_ =~ /mot1/)
{
#print "$_\n";
($valeur1,$mot1) = split(/=/,$_);
$mot1=~ s/\r//;
chomp($mot1);
$status = "OK";
}
if ($_ =~ /mot2/)
{
#print "$_\n";
($valeur2,$mot2) = split(/=/,$_);
$mot2=~ s/\r//;
chomp($mot2);
$status = "OK";
}
if ($_ =~ /mot3/)
{
#print "$_\n";
$status = "OK";
}
if ($_ =~ /mot4/)
{
#print "$_\n";
$status = "OK";
}
elsif ($status eq "KO")
{
$mot1 = "inexistant";
$mot2 = "inexistant";
$status = "KO";
#print "$status\n";
}
return $mot1;
return $mot2;
return $status;
}
# Mon script ne marche pas car le mot4 n'est pas present dans mon fichier, il me renvoi comme même OK :(
Merci pour votre aide
[Dal]
Messages postés
6174
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
2 février 2024
1 083
Modifié par [Dal] le 20/06/2013 à 15:24
Modifié par [Dal] le 20/06/2013 à 15:24
OK, peux-tu donner un exemple de fichier.txt correspondant à ce code ?
Dal
Dal
na_ba85
Messages postés
8
Date d'inscription
mardi 18 juin 2013
Statut
Membre
Dernière intervention
1 septembre 2017
20 juin 2013 à 15:43
20 juin 2013 à 15:43
oui voici un exemple général :
=======================================================
Fichier.txt
=======================================================
|-- ..............................
|-- mot1 = XXXXX # j'ai extrait cette valeur
|-- mot2 = XXXXX # j'ai extrait cette valeur
mot3 !!!
mot4 !! # lors de la verification d'un des fichiers, ce mot n'est pas present
=> Mon script doit lire le fichier et à chaque fois qu'il trouve un mot il passe au suivant ....
Si les 4 sont bien presents alors il me renvoi OK et si il en manque au moins un il me renvoi KO et arrete de lire mon fichier
=======================================================
Fichier.txt
=======================================================
|-- ..............................
|-- mot1 = XXXXX # j'ai extrait cette valeur
|-- mot2 = XXXXX # j'ai extrait cette valeur
mot3 !!!
mot4 !! # lors de la verification d'un des fichiers, ce mot n'est pas present
=> Mon script doit lire le fichier et à chaque fois qu'il trouve un mot il passe au suivant ....
Si les 4 sont bien presents alors il me renvoi OK et si il en manque au moins un il me renvoi KO et arrete de lire mon fichier
[Dal]
Messages postés
6174
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
2 février 2024
1 083
Modifié par [Dal] le 20/06/2013 à 18:26
Modifié par [Dal] le 20/06/2013 à 18:26
Bon, alors, je vais considérer que ce qui t'intéresse dans ton fichier, ce sont des lignes contenant :
C'est à dire des lignes commençant par mot1, mot2, mot3 et mot4 sans rien avant et sans rien après les valeurs "XXXXX" (il y a des "|-- " dans ton exemple avant le mot et des commentaires après).
D'autre part, je comprends que tu veux récupérer la valeur "XXXXX", etc., et mettre cela dans $valeur1, etc.
Le code suivant :
renvoie :
pour un fichier contenant :
et :
pour un fichier contenant :
Ce sont des exemples, car ne ne comprend pas bien ton code, qui visiblement est partiel, écrit des choses dans un fichier qui devrait être ouvert et qui ne l'est pas dans ce que tu adresses, etc., et le format de présentation des résultats n'est pas compréhensible pour moi.
Dans la mesure où tu utilises des variables globales, je ne vois pas ce que tu dois retourner avec "return" à la fin de la fonction Perl. Une chose est sûre, Perl s'arrêtera au premier "return".
Dans mon exemple ci-dessus, j'ai fait sans.
J'ai aussi utilisé une regexp avec capture, plutôt que faire une regexp puis un split (ce qui est à la fois plus robuste, rapide et plus concis).
Il y a du code dupliqué dans la fonction (que j'ai laissé pour coller à ton code, qui est déjà bien modifié). Dans un code plus refactorisé, on mettrait les mots et valeurs dans des tableaux, et on aurait un seul if dans la fonction (dans une boucle for, par exemple).
Une des principales erreurs dans ton code est qu'alors que tu utilises la fonction pour chaque ligne du fichier, tu en tires des conclusions en fin de chaque itération comme si tu avais analysé toutes les lignes. Ce n'est pas le cas. Le résultat final de l'analyse ligne par ligne ne peut se faire qu'en dehors de la boucle principale while (<LIRE_LOG>).
Dal
mot1 = XXXXX mot2 = YYYYY mot3 = ZZZZZ
C'est à dire des lignes commençant par mot1, mot2, mot3 et mot4 sans rien avant et sans rien après les valeurs "XXXXX" (il y a des "|-- " dans ton exemple avant le mot et des commentaires après).
D'autre part, je comprends que tu veux récupérer la valeur "XXXXX", etc., et mettre cela dans $valeur1, etc.
Le code suivant :
#!/usr/bin/perl use strict; use warnings; my $fic_log_uc = "fichier.txt"; my ($valeur1, $valeur2, $valeur3, $valeur4); my ($mot1, $mot2, $mot3, $mot4); my $status = 'KO'; $mot1 = $mot2 = $mot3 = $mot4 = "inexistant"; $valeur1 = $valeur2 = $valeur3 = $valeur4 = ""; open (LIRE_LOG, '<', $fic_log_uc) or die "Impossible d'acceder au fichier"; while (<LIRE_LOG>) { check(); } close (LIRE_LOG); if ( ($mot1 eq "inexistant") || ($mot2 eq "inexistant") || ($mot3 eq "inexistant") || ($mot4 eq "inexistant") ) { $status = "KO"; } else { $status = "OK"; } # do something with the acquired results print "$mot1;$valeur1;$mot2;$valeur2;$mot3;$valeur3;$mot4;$valeur4;$status\n"; exit; sub check { if ($_ =~ /^mot1\s*=\s*([^\s]+)\s*$/) { $mot1 = "mot1"; $valeur1 = $1; } if ($_ =~ /^mot2\s*=\s*([^\s]+)\s*$/) { $mot2 = "mot2"; $valeur2 = $1; } if ($_ =~ /^mot3\s*=\s*([^\s]+)\s*$/) { $mot3 = "mot3"; $valeur3 = $1; } if ($_ =~ /^mot4\s*=\s*([^\s]+)\s*$/) { $mot4 = "mot4"; $valeur4 = $1; } }
renvoie :
mot1;XXXXX;mot2;YYYYY;mot3;ZZZZZ;inexistant;;KO
pour un fichier contenant :
mot1 = XXXXX mot2 = YYYYY mot3 = ZZZZZ
et :
mot1;XXXXX;mot2;YYYYY;mot3;ZZZZZ;mot4;12345;OK
pour un fichier contenant :
mot1 = XXXXX mot2 = YYYYY mot3 = ZZZZZ mot4 = 12345
Ce sont des exemples, car ne ne comprend pas bien ton code, qui visiblement est partiel, écrit des choses dans un fichier qui devrait être ouvert et qui ne l'est pas dans ce que tu adresses, etc., et le format de présentation des résultats n'est pas compréhensible pour moi.
Dans la mesure où tu utilises des variables globales, je ne vois pas ce que tu dois retourner avec "return" à la fin de la fonction Perl. Une chose est sûre, Perl s'arrêtera au premier "return".
Dans mon exemple ci-dessus, j'ai fait sans.
J'ai aussi utilisé une regexp avec capture, plutôt que faire une regexp puis un split (ce qui est à la fois plus robuste, rapide et plus concis).
Il y a du code dupliqué dans la fonction (que j'ai laissé pour coller à ton code, qui est déjà bien modifié). Dans un code plus refactorisé, on mettrait les mots et valeurs dans des tableaux, et on aurait un seul if dans la fonction (dans une boucle for, par exemple).
Une des principales erreurs dans ton code est qu'alors que tu utilises la fonction pour chaque ligne du fichier, tu en tires des conclusions en fin de chaque itération comme si tu avais analysé toutes les lignes. Ce n'est pas le cas. Le résultat final de l'analyse ligne par ligne ne peut se faire qu'en dehors de la boucle principale while (<LIRE_LOG>).
Dal
na_ba85
Messages postés
8
Date d'inscription
mardi 18 juin 2013
Statut
Membre
Dernière intervention
1 septembre 2017
21 juin 2013 à 13:59
21 juin 2013 à 13:59
Bonjour Dal,
Je vous remercie enormement et grâce à vous j'ai compris mon erreur. En fait pour moi, il analyse que la ligne où je lui demande de chercher un mot particulier. Mais le fait que vous m'avez dit qu'il analyse ligne par ligne alors c'est normal qu'il me renvoi systematiquement OK car la dernier ligne comprend un de mes mots :(
j'ai essayé de comprende votre expression regulier :
/^mot1\s*=\s*([^\s]+)\s*$/
Celui-ci \s*([^\s]+)\s*$/ correspond à ma valeur.
Vous pouvez la signification \s car sur internet, ca signifie un separateur.
Encore merci :D
Je vous remercie enormement et grâce à vous j'ai compris mon erreur. En fait pour moi, il analyse que la ligne où je lui demande de chercher un mot particulier. Mais le fait que vous m'avez dit qu'il analyse ligne par ligne alors c'est normal qu'il me renvoi systematiquement OK car la dernier ligne comprend un de mes mots :(
j'ai essayé de comprende votre expression regulier :
/^mot1\s*=\s*([^\s]+)\s*$/
Celui-ci \s*([^\s]+)\s*$/ correspond à ma valeur.
Vous pouvez la signification \s car sur internet, ca signifie un separateur.
Encore merci :D
[Dal]
Messages postés
6174
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
2 février 2024
1 083
Modifié par [Dal] le 21/06/2013 à 15:18
Modifié par [Dal] le 21/06/2013 à 15:18
\s signifie un caractère "blanc", c'est à dire un espace ou une tabulation.
ce qui est capturé (ta "valeur") est ce qui est représenté entre parenthèses : ([^\s]+) signifie capture un ou plusieurs caractères qui se suivent et qui sont non "blancs" (les crochets servent à définir une liste de caractères acceptables, les faire précéder d'un ^ constitue une négation, le + signifie 1 ou plus de ces caractères ainsi définis).
les autres \s sont destinés à permettre d'ignorer les éventuels espaces, ou "blancs" qui figureraient de part et d'autre de la valeur (ainsi qu'à la suite du mot1 et à gauche du signe =).
Voilà le détail de l'explication de :
- à partir du début de ligne
- matche mot1
- suivit de zéro ou plusieurs "blancs" à la suite (espaces ou tabulations)
- suivis de =
- suivit de zéro ou plusieurs "blancs" à la suite
- on capture ensuite un ou plusieurs caractères à la suite qui ne sont pas des blancs
- ils peuvent être suivis de zéro ou plusieurs "blancs" à la suite jusqu'à la fin de la ligne
https://www.commentcamarche.net/contents/803-php-expressions-regulieres
Dal
ce qui est capturé (ta "valeur") est ce qui est représenté entre parenthèses : ([^\s]+) signifie capture un ou plusieurs caractères qui se suivent et qui sont non "blancs" (les crochets servent à définir une liste de caractères acceptables, les faire précéder d'un ^ constitue une négation, le + signifie 1 ou plus de ces caractères ainsi définis).
les autres \s sont destinés à permettre d'ignorer les éventuels espaces, ou "blancs" qui figureraient de part et d'autre de la valeur (ainsi qu'à la suite du mot1 et à gauche du signe =).
Voilà le détail de l'explication de :
/^mot1\s*=\s*([^\s]+)\s*$/
- à partir du début de ligne
- matche mot1
- suivit de zéro ou plusieurs "blancs" à la suite (espaces ou tabulations)
- suivis de =
- suivit de zéro ou plusieurs "blancs" à la suite
- on capture ensuite un ou plusieurs caractères à la suite qui ne sont pas des blancs
- ils peuvent être suivis de zéro ou plusieurs "blancs" à la suite jusqu'à la fin de la ligne
https://www.commentcamarche.net/contents/803-php-expressions-regulieres
Dal