[résolu] découper un fichier selon contenu de la ligne

découper un fichier selon contenu de la ligne [résolu] - Perl - Programmation

Marsh Posté le 16-01-2014 à 11:24:18    

Bonjour,
 
Le programme fourni par Gilou (lors de la discussion  "Découper un fichier en plusieurs et optimisation" - mai 2013) m'est particulièrement utile.
Cependant je cherche à le modifier quelque peu...
 
1) Je ne comprends pas les sens de "$. %" sur cette ligne :  

Code :
  1. if ($. % $maxline == 0)

.
 
2) J'essaie de modifier ce programme, pour que la découpe du fichier se fasse selon le contenu de la ligne (et non à la nième ligne).
Je souhaite découper le fichier quand la ligne commence par dièse, sachant que ce qui suit le dièse serait le nom à donner au fichier.
De type :
 

Code :
  1. # Global Variable
  2. my $FILENAME = 'test.txt';
  3.  
  4. #my $outname = "file";
  5. #my $fnum = 1;
  6. #open(my $fout, ">", $DIR.$outname.sprintf("%03d", $fnum++));
  7. open(my $fout, ">", $rep.$outname);
  8. $outname = "";
  9.  
  10. # Script
  11. open(my $fin, "<", $rep.$FILENAME);
  12.  
  13. while (<$fin> ) {
  14.  
  15. # if ($. % $maxline == 0) {
  16. if ($_ =~ /^#/) {
  17.   close($fout);
  18.   $outname = $_;
  19. $outname =~ s/#//;
  20.   #open($fout, ">", $rep.$outname.sprintf("%03d" . ".aa", $fnum++));
  21.   open($fout, ">", $rep.$outname);
  22. }
  23. else {
  24. print $fout $_;
  25. }
  26. }
  27. close($fout);
  28. close($fin);


 
ça ne fonctionne bien évidemment pas!
Je parviens à découper mon fichier si la ligne commence par "#", mais les nouveaux fichiers ne se nomme pas comme je le souhaite.
 
Quelqu'un peut-il me dire ce qui cloche.
 
D'avance merci,
 
Frelinf


Message édité par frelinf le 21-01-2014 à 15:28:47
Reply

Marsh Posté le 16-01-2014 à 11:24:18   

Reply

Marsh Posté le 17-01-2014 à 00:05:31    

Salut,
 
Tu peux essayer:

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4.  
  5. # Global Variable
  6. my $DIR = '/data/tmp/';
  7. my $FILENAME = 'fichier.csv';
  8. my $outname = "file";
  9. my $fnum = 1;
  10.  
  11. # Split file
  12. open(TOP, ">", $DIR.$outname.sprintf("%03d", $fnum++));
  13. open(FIN, "<", $DIR.$FILENAME);
  14. while (<FIN> ) {
  15.        chomp;
  16.        print TOP $_, "\n";
  17.        if (/\#/) {
  18.                my $line = $_;
  19.                $line =~ s/\#//;
  20.                close(TOP);
  21.                open(TOP, ">", $DIR.$line);
  22.        }
  23. }
  24. close(TOP);
  25. close(FIN);
  26.  
  27. __END__


Message édité par Sethenssen le 17-01-2014 à 00:11:01
Reply

Marsh Posté le 17-01-2014 à 10:37:58    

Bonjour,
 
merciiiiiiiii!
C'est impeccable.
 
Très bonne journée,

Reply

Marsh Posté le 21-01-2014 à 12:09:27    

Citation :

if ($. % $maxline == 0)


C'est pour déclencher une action toutes les maxlines lignes lues.
$. est une variable qui donne le numéro de la ligne en cours du dernier fichier ouvert.
Si un fichier est lu avec un while, ça donne le numéro de la ligne ligne traitée mise dans $_ mais par contre, si le fichier est lu avec un foreach, il est lu d'un seul coup, rangé dans un array, et c'est l'array qui est traité par la boucle, et dans ce cas, $. contient le nb de lignes du fichier.
A+,


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

Marsh Posté le 21-01-2014 à 12:19:56    

MERCI!
c'est parfaitement clair maintenant.
 
Comment je fais pour noter mon problème et ce message comme "[résolu]". J'ai mal dû regarder, j'ai pas vu l'info sur le forum...
 
Très bonne journée,
 
Frelinf
 

gilou a écrit :

Citation :

if ($. % $maxline == 0)


C'est pour déclencher une action toutes les maxlines lignes lues.
$. est une variable qui donne le numéro de la ligne en cours du dernier fichier ouvert.
Si un fichier est lu avec un while, ça donne le numéro de la ligne ligne traitée mise dans $_ mais par contre, si le fichier est lu avec un foreach, il est lu d'un seul coup, rangé dans un array, et c'est l'array qui est traité par la boucle, et dans ce cas, $. contient le nb de lignes du fichier.
A+,


Reply

Marsh Posté le 21-01-2014 à 15:07:40    

Il suffit d'éditer son message initial et d'ajouter [résolu] au titre.
 
 
Pour ton problème, j'aurais procédé ainsi:
 

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5.  
  6. # Global Variable
  7. my $dirname = '.';
  8. my $infilename = 'indata.txt';
  9. my $outfilename = 'outdata.txt';
  10.  
  11. # Script
  12. my ($infile, $outfile);
  13. open($infile, "<", $dirname.'/'.$infilename);
  14. while(<$infile> ) {
  15.    if (/^#(.*[^\s\t\n])(\s\t\n)*/) {
  16.         close $outfile unless ($. == 1);
  17.         open($outfile, ">", $dirname.'/'.$1);
  18.         next;
  19.    }
  20.    open($outfile, ">", $dirname.'/'.$outfilename) if ($. == 1);
  21.    print $outfile  $_;
  22. }
  23. close $outfile;
  24. close $infile;
  25.  
  26. __END__


La subtilité est que si la première ligne commence avec un #, on peut éviter de créer un fichier par défaut inutile, d'ou les tests avec $. == 1
A+,
 

Reply

Marsh Posté le 21-01-2014 à 15:28:27    

effectivement, résultat très propre, très pro!

Reply

Sujets relatifs:

Leave a Replay

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