Manipulation basique de fichier texte a l'aide de Perl

Manipulation basique de fichier texte a l'aide de Perl - Perl - Programmation

Marsh Posté le 05-11-2009 à 23:54:32    

Bonjour a tous,  
 
J'ai un algorithme de simulation qui me genere des fichiers textes assez gros et tjs organise de la mm facon:  
 
Un entete d'une vingtaine de ligne avec les parametres de simulation globaux.  
Un numero de famille, une ligne ressmble a ca:  
Family Number 1
Un entete propre a la simulation menee ici (imaginons que les 50 premieres familles fassent varier l'angle, dans cet entete, seul l'angle va changer, si les familles 50 a 1000 font varier la temperature, seule la temperature variera etc)
Les resultats dans 5 colonnes qui s'etalent sur un nombre de lignes fixes
 et ainsi de suite, les familles, leurs entete et les colonnes de resultat se suivent.  
 
Bon.  
 
Je suis novice en Perl mais je me dis que ce langage semble parfaitement adapte a mon besoin cependant j'ai des difficultes avec la synthaxe un peu particuliere.  
Mon idee, c'est d'ouvir le fichier, rechercher Family Number, reperer le numero de famille, etre capable de prendre les resultats de la famille n a m et de les concatener dans un fichier de sortie que je vais plotter avec gnuplot (ca je maitrise par contre :D ).  
Mon probleme, je suis incapable d'aboutir lors de la recherche, j'ai essaye de choper des bouts de code a droite et a gauche vu que le net fourmille d'exemples mais ca ne donne aucun resultat.  
Est ce que qqun pourrait me detailler la boucle qui va scanner le fichier.txt jusqu'a trouver la ligne et extraire le numero? Apres je pensais utiliser awk, un collegue m'a montre que c'etait simple.  
Mais la je perds un temps fou a capter comment fonctionne les m/\b etc pour zero resultat.  
J'ai teste pas mal d'operations simples, copier etc et ca semble fonctionner, j'aurais besoin d'un coup de main pour le while(<input> ){} qui va chercher Family Number, trouver le numero correspondant, sauter les lignes d'entete (a terme je veux mm recup les parametres pour en faire une colonne et automatiser le plotting sous gnuplot) pour choper les 6 colonnes de resultats etalees sur 30 40 lignes. En fait je patauge dans les expressions regulieres plus que dans l'algorithmie a vrai dire.  
 
Merci pour votre aide  [:daaadou:1]

Reply

Marsh Posté le 05-11-2009 à 23:54:32   

Reply

Marsh Posté le 06-11-2009 à 01:04:05    

Salut a toi,
 
Je pense surtout que tu as adopté une mauvaise méthode : te lancer dans une tâche sans avoir suffisamment préparé le terrain.
 
Perl est certes adapté à cette tâche, mais probablement n'importe quel outil de scripting l'est. Il ne s'agit donc pas tant d'une problématique de langage que d'algo.
 
Si j'ai bien compris ton souci, ca se ramène à la problématique suivante :
 
Ouvrir un fichier (lecture en mode ligne par ligne)
sauter un nombre fixe de lignes
Boucle sur les family number
Sauter un nombre de lignes dépendant du type de famille
Copier un certain nombre de lignes
Fin de boucle
 
Les regexp c'est comme les antibiotiques, c'est pas automatique. En l'occurence Perl comme n'importe quel langage a des fonctions de comparaisons de chaines de caractère (pour identifier tes family number ou tes lignes de résultat), et des fonctions pour éclater des lignes selon un séparateur défini.
 
Vu ce que tu présentes, il n'y a aucune difficulté à traduire ton "algo" (si tant est qu'il est assez complet) en code de n'importe quel langage.

Reply

Marsh Posté le 06-11-2009 à 15:04:06    

Citation :

Perl est certes adapté à cette tâche, mais probablement n'importe quel outil de scripting l'est.

Sauf que Perl est particulièrement adapté a faire des recherches sur de gros fichiers texte, c'est pas par hasard qu'il est employé pour faire du pattern matching sur de longues séquences d'ADN.

 

Bon, je t'ai codé en vitesse un exemple de ce que ca pourrait donner en perl (j'ai pas testé, mais ca devrait te donner une idée de comment procéder)

Code :
  1. #!/usr/bin/perl -w
  2. use warnings;
  3. use strict;
  4.  
  5. my $filename = "data.txt";
  6. open my $file, '<', $filename or die "Ouverture de $filename impossible\n";
  7. my $patternfound = 0;
  8. my $skippedlines = 0;
  9. my $storedlines = 0;
  10. while (<$file> ) {
  11.    if ($patternfound) {
  12.        ++$skippedlines;
  13.        if ($skippedlines > 10) { # on saute 10 lignes
  14.            if (storedlines < 5) { # puis on en envoie 5 en sortie
  15.                ++storedlines;
  16.                print $_;
  17.            }
  18.            else {
  19.                #on a imprime les 5 lignes on repasse en recherche de pattern
  20.                $patternfound = 0;
  21.                $skippedlines = 0;
  22.                $storedlines = 0;
  23.            }
  24.        }
  25.    }
  26.    else { #recherche de pattern
  27.        if (/^Family Number \d+$/) {
  28.            $patternfound = 1;
  29.        }
  30.    }
  31. }
  32. close $file or die "Fermeture de $filename impossible\n";


A+,

 


Message édité par gilou le 09-11-2009 à 10:06:13

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 06-11-2009 à 15:11:41    

Notes que ensuite, quand tu sauras un peu manipuler perl, ce code est un poil améliorable en qualité en ce qui concerne les entrées sorties, par l'utilisation de modules.

Code :
  1. use IO::File;
  2. ....................
  3. my $file = IO::File->new($filename, "r" );
  4. unless (defined $file) { die "Ouverture de $filename impossible\n"; }
  5. while (<$file> ) {
  6. .................
  7. }
  8. undef($file);


A+,


Message édité par gilou le 06-11-2009 à 15:11:55

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 09-11-2009 à 07:12:44    

Merci beaucoup à vous deux, je regarde ça demain au taf :jap:  

Reply

Marsh Posté le 09-11-2009 à 10:09:42    

Tiens d'ailleurs en relisant, j'ai vu un truc qui marchait pas dans ce que j'avais écrit et j'ai corrigé (remplacé le while interne par un if).
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed