Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1702 connectés 

  FORUM HardWare.fr
  Programmation
  Perl

  Test chaine dans un fichier

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Test chaine dans un fichier

n°2238140
coolkis
Posté le 17-09-2014 à 15:42:51  profilanswer
 

Bonjour,
 
J'aimerai tester si des valeurs sont présentes dans un fichier texte ou non.
J'ai commencé le code suivant mais il ne fonctionne que s'il y a qu'une valeur dans mon fichier texte.
 
Ex du fichier txt :
 
test1
test2
 
Voici mon code :

Code :
  1. open(FILE,"$file" ) || die ("Erreur d'ouverture du fichier" ) ;
  2. while (<FILE> ) {
  3.   $_ =~ s/\n//g;
  4.   if ($_ eq $ligne) {
  5.       print "Fichier deja present\n";
  6.   } else {
  7.       print "Fichier $ligne non present\n";
  8.   }
  9. }


 
Admettons que la variable $ligne soit égale à test1, le code me renvoi les deux tests, c'est à dire :
Fichier test1 non present
Fichier deja present
 
Est ce que quelqu'un pourrait m'aider à comprendre mon erreur svp ?
Merci

mood
Publicité
Posté le 17-09-2014 à 15:42:51  profilanswer
 

n°2238153
gilou
Modérateur
Modzilla
Posté le 17-09-2014 à 18:41:02  profilanswer
 

Bonsoir,
C'est normal, vu que ton while execute le test ligne par ligne.
Pour la ligne égale a test1, le test est OK et ça imprime  "Fichier deja present", et pour la ligne a test2, le test est  pas vérifié, et ça imprime "Fichier $ligne non present"
Une solution:
Créer une variable a valeur 0 et la passer a 1 (et sortir de la boucle while) si le test est verifié (cf last en perl).
Et une fois la boucle terminée, imprimer selon la valeur de cette variable (elle est toujours a 0 si aucune ligne n'était égale a test1)
Autre remarque, quand on fait un open, il est bon de faire aussi un close.
 
A+,


Message édité par gilou le 17-09-2014 à 18:45:55

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2238158
coolkis
Posté le 17-09-2014 à 18:55:19  profilanswer
 

Merci Gilou pour ta réponse.
Oui bien sur j'ai fais un close, j'ai simplement pas affiché tout le code.
 
Par contre est ce que ta solution fonctionne pour une multitude de fichier ?
Car j'ai mis l'exemple de deux fichiers mais dans la réalité dans ce fameux fichier texte, il y aura des centaines de fichiers !
 
Autre chose aussi ! Le programme doit vérifier la présence également de plusieurs fichiers dans le fichier texte.

n°2238166
gilou
Modérateur
Modzilla
Posté le 17-09-2014 à 23:58:33  profilanswer
 

> Le programme doit vérifier la présence également de plusieurs fichiers dans le fichier texte.
 
Dans ce cas la, au lieu d'une variable, tu crées un hash
my %hash
et si tu as un test validé  
if ($_ eq "test18" )
par exemple
tu fais
$hash{"test18"}++;
et tu ne sors alors pas du while avec un last (c'était bon que si on recherchait une seule valeur, cette optimisation)
une fois le while terminé les clés du hash seront les valeurs détectées dans le fichier par les tests.
 
A+,


Message édité par gilou le 18-09-2014 à 00:00:22

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2238189
coolkis
Posté le 18-09-2014 à 13:04:29  profilanswer
 

Bonjour Gilou,
J'ai regarder ce que c'était le hash donc j'ai bien compris que c'était associé à un tableau !
Par contre étant vraiment novice, j'ai du mal à mettre ça en place et à m'en sortir.
 
Pourrais-tu me guider un peu plus stp ?
En attendant merci de ton aide.

n°2238207
gilou
Modérateur
Modzilla
Posté le 18-09-2014 à 13:53:13  profilanswer
 

Ben un truc comme ceci:

Code :
  1. #!/usr/bin/perl
  2.  
  3. use strict;
  4. use warnings;
  5. use autodie;
  6.  
  7. my $filename = "testkw.txt";
  8. my @keywords = qw(toto tata tutu);
  9. my %kwfound;
  10.  
  11. open my $fh, "<", $filename;
  12. while (<$fh> ) {
  13.  s/\n$//o;
  14.  foreach my $kw (@keywords) {
  15.    if ($_ eq $kw) {
  16.      ++$kwfound{$kw};
  17.    }
  18.  }
  19. }
  20. close $fh;
  21.  
  22. foreach my $kw (keys %kwfound) {
  23.  print "keyword $kw found in $filename\n";
  24. }
 

A+,


Message édité par gilou le 18-09-2014 à 13:54:32

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2238228
gilou
Modérateur
Modzilla
Posté le 18-09-2014 à 14:38:37  profilanswer
 

coolkis a écrit :

Bonjour Gilou,
J'ai regarder ce que c'était le hash donc j'ai bien compris que c'était associé à un tableau !


En perl, les types composites sont la liste et le hash.
Un hash c'est une variable associée a une sorte de tableau, mais dans lequel les éléments, au lieu d'être indexés par des entiers comme dans une liste, sont indexés par des valeurs uniques, les clés.
 
my %kwfound;  # je déclare un hash, kwfound
++$kwfound{$kw}; # perl cherche si le hash kwfound a une entrée pour la clé de valeur $kw. Si oui, il incrémente la valeur de 1 (le ++), sinon, il crée dans kwfound une nouvelle entrée pour la cké de valeur $kw, et comme on veut faire une opération numérique dessus, il l'initialise a 0, puis il l'incrémente (le ++) et la valeur sera alors 1.
 
A+,
 


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2238243
coolkis
Posté le 18-09-2014 à 16:01:10  profilanswer
 

Ok super ! Merci bcp encore, j'ai bien compris le fonctionnement.
Par contre si le fichier recherché n'est pas dans le fichier texte, je voudrais l'ajouter !
 
Est ce que cela se passe dans le "foreach" ?

n°2238272
gilou
Modérateur
Modzilla
Posté le 18-09-2014 à 18:16:41  profilanswer
 

Non.
Il faudra rouvrir le fichier texte en écriture, en mode ajout à la fin, et écrire la ligne manquante dedans.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2238344
coolkis
Posté le 19-09-2014 à 14:10:13  profilanswer
 

Oui je suis bien d'accord.
 
Je comptais faire un truc du genre :
 
foreach my $kw (@keywords) {
    if ($_ eq $kw) {
      ++$kwfound{$kw};
    } else {
         ajout du fichier...
    }
}
 
Ce n'est pas la bonne méthode ça ?

mood
Publicité
Posté le 19-09-2014 à 14:10:13  profilanswer
 

n°2238357
gilou
Modérateur
Modzilla
Posté le 19-09-2014 à 15:02:40  profilanswer
 

Non, c'est pas à ce niveau la, puisque le test foreach my $kw (@keywords) se fait ligne a ligne.
 
Par contre, quand on aura fini de lire le fichier, plutôt que  
 
    foreach my $kw (keys %kwfound) {
     print "keyword $kw found in $filename\n";
    }
 
on peut faire
 
foreach my $kw (@keywords) {
    # si on ne l'a pas trouvé dans le fichier texte
    if (!defined($kwfound{$kw})) {
         ajout du fichier...
    }
}  
 
et pour que ça marche, il faut  
1) avoir ouvert le fichier en lecture/écriture
2) le fermer après tout ça et non plus avant
Comme après le remplissage de %kwfound on a lu tout le fichier, on est en fin de fichier, et donc on peut ajouter du texte sans craindre d'écrire par dessus du contenu féjà présent.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2238379
coolkis
Posté le 19-09-2014 à 16:41:06  profilanswer
 

Une fois de plus, merci beaucoup pour ton aide Gilou.
 
Voici ce que ça donne :
 
foreach my $kw (@keywords) {
  if (!defined($kwfound{$kw})) {
    open(FILE, ">>$filename" ) || die ("Erreur d'ouverture du fichier" );
    print FILE "${kw}\n";
  } else {
      print "Fichier $kw deja present $filename\n";
  }
}
close (FILE);

n°2238381
gilou
Modérateur
Modzilla
Posté le 19-09-2014 à 17:03:01  profilanswer
 

> open(FILE, ">>$filename" )  
Surtout pas!
Tu vas pas ouvrir le fichier une fois par mot manquant et jamais le refermer...
 
Le plus simple c'est d'ouvrir en read-write le fichier au départ
open my $fh, "+<", $filename;
 
et de faire à la fin
 
foreach my $kw (@keywords) {
  if (!defined($kwfound{$kw})) {
    print $fh "${kw}\n";
  } else {
      print "Fichier $kw deja present $filename\n";
  }
}
close $fh;
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2238390
coolkis
Posté le 19-09-2014 à 18:19:52  profilanswer
 

Ok ! En fait j'avais déjà fait un << close $fh; >> avant la boucle, c'est pour cela que j'ai refais un open derrière. Mais effectivement c'est plus propre comme cela ;-)


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Perl

  Test chaine dans un fichier

 

Sujets relatifs
C++ : Ajouter une ligne à un fichier txtCharger une image ou fichier dans excel via macro
Batch de copie de fichier et planificateur de tâcheCréation d'un script ou btach de copie de fichier sous windows
Récupération fichier plus récentpeupler une ontologie a partir d'un fichier xmi
Fichier bloqué par 1&1, vous parait-il normal ?Script affichage taille fichier
Ecrire dans un fichier binaireconversion de fichier .cds -> .xls
Plus de sujets relatifs à : Test chaine dans un fichier


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR