PERL: Recupérer une donnée sur un fichier texte [Résolu/Fermé]

Messages postés
55
Date d'inscription
mercredi 14 mai 2014
Statut
Membre
Dernière intervention
4 octobre 2016
- - Dernière réponse : [Dal]
Messages postés
5302
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
6 décembre 2019
- 16 mai 2014 à 15:53
Bonjour à tous,
Je viens de commencer le PERL depuis ce début de semaine (j'ai surtout des compétances en C). Il se trouve que je veux l'utiliser pour le traitement de plusieurs données (2000 par tranche de 50 a 100).

Pour le traitement sur un logiciel propre, je dois lui apporter un fichier .rub contenant l'information, ainsi que des données que je dois remplir dans un panneau.
J'ai reussis à récupérer toutes ces données sauf une, qui elle se trouve dans un fichier texte.
Cette information n'est pas forcément présente.
Elle se trouve précédé par "IRRADIATION:" et suivi d'un retour à la ligne.

Petite information sur le reste du script:
-Création d'un fichier listant tous les .rub
-Tous les fichiers .rub sont dans un tableau
FOR
-Les infomations contenus dans le nom sont enregistrées
//La intervient l'acquisition de cette autre donnée
-Injection des données dans le logiciel
fin for.

Je sais pas si j'ai été clair.
Je parcours les autres sujets car il y ne a qui y ressemblent mais je comprends pas tout

Merci d'avance
Afficher la suite 

12 réponses

Messages postés
5302
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
6 décembre 2019
830
0
Merci
Salut Akre66,

Peux-tu donner un exemple représentatif de fichier où se trouve l'information à capturer en indiquant précisément de ce tu veux récupérer ?

Dal
Messages postés
55
Date d'inscription
mercredi 14 mai 2014
Statut
Membre
Dernière intervention
4 octobre 2016
0
Merci
Le message est du type:
(j'ai mis des X pour les informations pour des raisons de sécurité)

Unit name: XXXXXXXXXX
Date: XX/X/XX
Cycle: X
Map: XX

User comments:

TRANCHE: X

DU: XX XX XX XX XX

NO: XX

CAMPAGNE: X

IRRADIATION: 5306
ENERGIE: XXXXXXXX

PUISSANCE: XXX

ELECTRIQUE: XXXX

CB: XXX

RR: XXX
Messages postés
55
Date d'inscription
mercredi 14 mai 2014
Statut
Membre
Dernière intervention
4 octobre 2016
0
Merci
J'ai fini le code sauf cette partie.

J'ai cherché un peu sur internet, j'ai pensé à une piste.
Mais je sais pas comment faire la sythnaxe donc j'explique l'idée

A l'aide d'un grep dans une if je verifies si la donnée est présente.

1er cas: Elle y est. Avec une grep je récupére la ligne. Sur cette ligne je lui demande d'enlever tous les lettres et le ":". Comme ça je garde le nombre que je garde.

2eme cas: elle y est pas et avec une die je stoppe.
Messages postés
5302
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
6 décembre 2019
830
0
Merci
Salut Akre66,

Tu n'as pas utilisé la balise <code> pour poster ton exemple de données, aussi je ne suis pas sûr que le formatage qui apparaît là soit le bon. En regardant le source html de ton post, il semblerait que le format correct soit celui-ci :

Unit name: XXXXXXXXXX
Date: XX/X/XX
Cycle: X
Map: XX

User comments:

    TRANCHE: X

    DU: XX XX XX XX XX

    NO: XX

    CAMPAGNE:  X

    IRRADIATION: 5306
    ENERGIE: XXXXXXXX

    PUISSANCE: XXX

    ELECTRIQUE: XXXX

    CB: XXX

    RR: XXX


et que tu veuilles donc matcher ce qui figure en ligne 16 ci-dessus, et récupérer "5306".

Cette ligne comporte en début de ligne un espace blanc (plusieurs caractères espace ou tabulation), puis "IRRADIATION:" puis un espace blanc et ce que tu veux capturer, qui est de la forme : un ou plusieurs caractères décimaux sans virgule ni point.

Cela correspond à la regexp suivante :
/^\s+IRRADIATION:\s(\d+)/
.
Donc, un code similaire au code qui suit devrait faire l'affaire :

#!/usr/bin/perl
use strict;
use warnings;

my $ligne;
my $filename = "akre66_test.txt";
my $fh;

open ($fh, '<', $filename) 
    or die "Impossible d'ouvrir le fichier $filename en lecture";               

foreach $ligne(<$fh>) 
{
    if ($ligne =~ /^\s+IRRADIATION:\s(\d+)/){
        print "IRRADATION trouvée = $1\n";
        last;
    }
}
close $fh;


Dal
Messages postés
55
Date d'inscription
mercredi 14 mai 2014
Statut
Membre
Dernière intervention
4 octobre 2016
0
Merci
Désolé pour le retard.
Alors pour le texte, j'ai fais un copier-coller, mais ça vient d'un fichier texte, et il se présente comme ça avec les saut de ligne. Après y a pas les X.

J'ai compris ton code je crois. Je l'ai essayé hier j'ai pas réussi...

Après je suis parti sur ça:

###Donne à partir du commentaire###

$com="$site1"."$tranche"."$cycle"."$numero"."com";
print "$com \n";
open(COM,"$home/testcom/$com") or die("Fichier commentaire n'est pas au bon format");
@com=<COM>;

$com1=grep('IRRADIATION:',@com);
@com1=split(':',$com);


close(COM);

J'ai verifié, il ouvre le bon fichier tout le temps. Le soucis se trouve dans mon grep je crois. J'ai essayé en utilisant regexp que tu m'as filé mais ça marche pas.
J'ai l'impression de bien utiliser le grep mais pet etre pas.

La console ne m'affiche pas d'erreur mais juste des nombre qui correspondent à rien.
Messages postés
5302
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
6 décembre 2019
830
0
Merci
Si la regexp ne fonctionne pas, c'est que le format que je pensais exact ne l'est pas, et qu'une regexp opérant un contrôle moins strict du type
/.*IRRADIATION:\s(\d+)/
pourrait passer.

Si tu tiens à utiliser grep, il faut l'utiliser correctement : http://perldoc.perl.org/functions/grep.html

Le grep de Perl renvoie un tableau, et non pas un scalaire, et le premier argument est une regexp, et donc doit être entre "/ /". Utilises-tu les directives
use strict;
et
use warnings;
?

Ensuite, le split va te splitter autour d'un caractère, et donc si tu splittes avec ":", tu vas tu vas prendre en 2ème résultat un espace, ton nombre et le retour à la ligne.

Avec grep, un code comme celui-ci fonctionne chez moi, que "IRRADIATION" soit précédée de quelque chose ou pas :

#!/usr/bin/perl
use strict;
use warnings;

my $filename = "akre66_test.txt";

my $FICH_COM;
my @com;
my @irrad;

open($FICH_COM,$filename) or die("Fichier commentaire n'est pas au bon format");
@com = <$FICH_COM>;

@irrad = grep(/IRRADIATION:/, @com);
if (@irrad != 1) {
    print "Erreur : il y a plus d'une ligne IRRADIATION\n";
    exit;
}
    $irrad[0] =~ s/.*IRRADIATION: (\d+).*/$1/;
    chomp $irrad[0];                                                                                                                                                                                               
    print "IRRADIATION trouvée, elle vaut : $irrad[0]\n";

close($FICH_COM);


Dal
Messages postés
55
Date d'inscription
mercredi 14 mai 2014
Statut
Membre
Dernière intervention
4 octobre 2016
0
Merci
C'est bon ça tourne impec. J'ai même mis une condition quand il y a pas l'information pour continuer le programme.
Merci.

Par contre j'ai un soucis, mon information sort avec XXXX <cr><cr>.
Avec XXXX ma donnée que je veux récupérer et <cr> qui est une ou plusieurs fois.

J'ai pensé à substitute:

($bu=$bu)=~s/<c>//;
Messages postés
55
Date d'inscription
mercredi 14 mai 2014
Statut
Membre
Dernière intervention
4 octobre 2016
0
Merci
Désolé pour le dobule post, mais j'ai oublié de préciser:

Que ce code marde pas...
Messages postés
5302
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
6 décembre 2019
830
0
Merci
c'est quoi
<cr><cr>
, ce sont ces caractères qui apparaissent ou veux tu dire qu'il y a des retours à la ligne ?
Messages postés
55
Date d'inscription
mercredi 14 mai 2014
Statut
Membre
Dernière intervention
4 octobre 2016
0
Merci
c'est bon j'ai trouvé le probleme.
Je le voyais comme une chaine de carractère mais en réalité c'est le retour chariot mal traduis entre ma base de donnée et mon pc.
Bref tout est bon
Messages postés
55
Date d'inscription
mercredi 14 mai 2014
Statut
Membre
Dernière intervention
4 octobre 2016
0
Merci
merci Dal :)
Messages postés
5302
Date d'inscription
mercredi 15 septembre 2004
Statut
Contributeur
Dernière intervention
6 décembre 2019
830
0
Merci
ah, ok, content pour toi :-)

pour supprimer un retour à la ligne éventuellement présent à la fin de ta variable, tu utilises chomp :

http://perldoc.perl.org/functions/chomp.html

comme chomp renvoie 1 si un retour à la ligne a été supprimé (et 0 sinon), tu peux supprimer tous retours à la ligne pouvant être présents, quelqu'en soit le nombre, avec un while, comme cela :

my $st = "toto\n\n\n";
while (chomp $st){};