Forum Programmation.perl incrémenter les lignes d'un fichier et découper à 30 lignes et passer à une nouvelle page

Posté par  . Licence CC By‑SA.
Étiquettes : aucune
-1
30
avr.
2015

Salut à tous, j'aimerai écrire un code qui incrémente les lignes d'un fichier et découpe lorsqu'il atteint 30 lignes ensuite passer à une nouvelle page toujours découpée en 30 lignes. Car mon fichier d'entrée en possède plus de 4000 lignes. que je dois découper
voici une approche de ma part:

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

open(my $fhin, '<', 'result_1.csv')or die "Unable to open file"; 


open(my $fhout, '>', 'result_2.csv')or die "Unable to open file";

my $lines = 0;
while(sysread fhin,$lines++ < 3500) {
    print $fhout "$lines\n"; 
    print $fhout "New Table\n" if ($lines % 30 == 0);
}
  • # Problème ?

    Posté par  . Évalué à 1.

    Bonjour,

    Quel est le problème ?

    Je ne connais pas bien perl, mais je suppose que le fait de fermer $fhin immédiatement s'il n'y a pas d'erreur à son ouverture va être gênant dans la boucle de lecture…

    Donc indiquer en plus l'erreur ou le point de bloquage permettrait de mieux vous orienter.

    Matricule 23415

  • # code non valide

    Posté par  (site web personnel) . Évalué à 1.

    La première chose à faire en perl est de vérifier que le code est valide, avec la commande : perl -cw, ce qui donne

    $ perl -cw essai.pl 
    Unquoted string "fhin" may clash with future reserved word at essai.pl line 11.
    Can't modify numeric lt (<) in sysread at essai.pl line 11, near "3500) "
    Not enough arguments for sysread at essai.pl line 11, near "3500) "
    essai.pl had compilation errors.

    Ensuite il y a des problèmes avec les instructions close :
    * le premier close est mal placé
    * il manque le close sur le fichier en sortie

    Je te recommande d'utiliser l'outil perlcritic pour vérifier tes codes perl : il vérifie les "bonnes pratiques" de codage et permet ainsi d'éviter pas mal d'erreurs.

    • [^] # Re: code non valide

      Posté par  . Évalué à -1.

      J'ai efface perl close(fhin) je m'escuse d'avoir oublier cela.

      comme tu l'a demander je m'explique de nouveau J'ai un fichier fhin-CSV (4000 Noms) avec des résultats, chaque ligne a un nom, mais les deux premières lignes de fhin ne doivent pas apparaître dans le fichier de sortie fhout, je veux créer plusieurs pages de fhout, a chaque page doit être mentione 30 noms, ensuite 30 noms sur la prochaine page, et ainsi de suite.

  • # Comment poser une question

    Posté par  . Évalué à 4. Dernière modification le 01 mai 2015 à 10:35.

    Ta description très courte du problème et ton code sans plus d'infos permettront difficilement de t'aider sereinement. En gros, il faut qu'on devine le problème, ça prend du temps, on peut mal deviner et, au final, te poster une solution qui ne répond pas à ton problème ; personne ne s'y retrouve à la fin.

    Pour maximiser tes chances que quelqu'un puisse et veuille t'aider, tu dois poster :

    • une description la plus claire possible de ce que tu veux faire, avec des exemples (simplifiés si besoin) d'entrées et sorties attendues.
    • expliquer ce que tu as déjà essayé et pourquoi ça n'a pas marché, qu'est-ce qui te bloque, donc, au minimum, les éventuels messages d'erreurs qui devraient apparaître vu que tu as correctement mis use strict; et use warnings;. Bref, tu dois faciliter le travail de ceux dont tu demandes l'aide, et surtout leur fournir les informations qu'ils ne peuvent pas s'inventer.
    • donner l'impression que tu as fait tes devoirs et que tu veux apprendre, c'est-à-dire laisser comprendre que tu seras content du moindre indice que l'on puisse te donner et qui puisse te permettre de te débloquer.

    Parfois, si tu as réussi à bien cerner ton problème, tu pourras simplifier ta question et donner juste les infos que tu crois utiles, mais, au moindre doute, mieux vaut y aller méthodiquement.

    Plus tu consacrera de temps à bien rédiger ta question, plus il y a de chances que tu obtiennes ce que tu veux. Il se peut même parfois que, en écrivant ta question consciencieusement, tu résolves tout seul le problème avant de la poster.

    • [^] # Re: Comment poser une question

      Posté par  . Évalué à -1.

      Merci bien des details je suis desole que personne ne me comprenne, je m'xplique encore j'aiun fichier fhin possedant des noms exemple:

      fhin-csv
      Mon resultat possede
      les nom sont 10 noms:
      Name0
      Name1
      Name2
      Name3
      Name4
      Name5
      Nmae6
      Name7
      Name8
      Name9

      disont je decoupe ce fichier fhin en plusieurs fichiers fhout ayant chacun 3 Nom par fichier et en tenant compte que le 2 premieres ligne a savoir:
      Mon resultat possede
      les noms sont 10 noms:
      n'apparaise pas sur le mon premier fichier fhout1 ainsi j'aurai enfin de compte 4 fichiers fhout:
      - fhout1 - fhout2 - fhout3 - fhout4
      - Name0 - Name3 - Name6 - Name9
      - Name1 - Name4 - Name7
      - Name2 - Name5 - Name8

      • [^] # Re: Comment poser une question

        Posté par  . Évalué à 2.

        Voici un script qui résout cet exemple (si j'ai bien compris maintenant) :

        #!/usr/bin/env perl
        
        use strict;
        use warnings;
        
        open(my $fh, '<', 'input.csv') or die $!;
        
        my $n = 0;    # compteur pour les noms des fichiers produits
        my $fh_out;
        open($fh_out, '>', "output-$n.csv") or die $!;
        
        while (my $line = <$fh>) {
            print $fh_out $line;
            if ($. % 3 == 0) {
                close $fh_out;
                # on ouvre un nouveau fichier
                $n++;
                open($fh_out, '>', "output-$n.csv") or die $!;
            }
        }

        En particulier, remarque bien que sysread n'est pas la façon la plus simple de lire un fichier. Je te laisse l'adapter.

        • [^] # Re: Comment poser une question

          Posté par  . Évalué à -2.

          Salut Anaseto,
          juste pour mensionner que ton code ne me suprime pas les 2 premieres lignes du fichier input
          mais je pourrai le ressoudre. Grand merci de ta propositon.

      • [^] # Re: Comment poser une question

        Posté par  . Évalué à 2. Dernière modification le 01 mai 2015 à 11:51.

        Ouah, mets directement un exemple, c'est tout de suite plus clair…

        Si tu galère à coder , un outil tout prêt pour ça: split (man split ou split --help pour les explications)

        split -l 3 -d result_1.csv fhout

        En perl vite fait toujours sur ton exemple avec quelques explications

        use strict;
        use warnings;
        
        open IN,'result_1.csv';
        
        my $count_lines = 0;
        my $ind=1;
        my $content="";
        my $split_length=3; # nombre de lignes attendues / fichier splitté
        for my $line (<IN>) {
            if($count_lines && $count_lines%$split_length==0){ #ecrit les lignes déjà lues par $split_length
              open OUT, ">fhout".$ind;
              print OUT $content;
              close OUT;
                  # on avance les compteurs et on repart à zéro pour stocker les lignes
              $ind++;
              $content=$line;
              $count_lines++;
            }
            else{
                  # on stocke les lignes
              $content.=$line;
              $count_lines++;
            }
        }
        #Si on ne finit pas sur un multiple de $split_length, on print le reste dans un dernier fichier
        if($content ne ""){
              $ind++;
              open OUT, ">fhout".$ind;
              print OUT $content;
              close OUT;
        }
        close IN;

        Et bé, grillé par une version bien plus optimisé :)

  • # man split

    Posté par  . Évalué à 3. Dernière modification le 01 mai 2015 à 11:35.

    split - Découper un fichier en plusieurs partie
    
    -l, --lines=NOMBRE
              écrire NOMBRE lignes par fichier de sortie
    

    Cette commande devrait te produire le résultat voulu :

    split -l 30 -d --additional-suffix=.csv fichier.csv result_

    Edit: Heu, oui en faite l'énoncé n'est pas très clair. Mais bon avec plusieurs fichiers, ça sera plus facile à les numéroter, je pense.

    • [^] # Re: man split

      Posté par  . Évalué à -1.

      Tres tres grand Merci a vous tous, c'est tres aimable de votre part, vraiment tres tres grand Merci.

  • # split, tail, head

    Posté par  . Évalué à 3.

    tail ou head pour prendre seulement les X lignes (-2 du debut)
    split pour couper le resultat en bloc de 30.

    ca pourrait faire un truc (non testé) du genre :

    tail -n5000 -n-2 fichier.csv | split -l 30

    evidemment ca demande d'etre sous linux pour avoir tail

    • [^] # Re: split, tail, head

      Posté par  . Évalué à 2. Dernière modification le 03 mai 2015 à 07:28.

      je travaille sous windows

      • [^] # Re: split, tail, head

        Posté par  . Évalué à 2. Dernière modification le 03 mai 2015 à 09:53.

        Les outils GNU pour Windows : https://github.com/bmatzelle/gow/releases

        Une meilleure invite de commande pour Windows : ConEmu : http://www.hanselman.com/blog/ConEmuTheWindowsTerminalConsolePromptWeveBeenWaitingFor.aspx

        (ou ConsoleZ si on préfère mais perso je préfère ConEmu)

        Les deux peuvent aussi utiliser un autre shell (zsh, bash, …) du moment qu'on l'a en version compilé pour Windows (enfin il paraît, je l'ai pas fait).

        "Quand certains râlent contre systemd, d'autres s'attaquent aux vrais problèmes." (merci Sinma !)

      • [^] # Re: split, tail, head

        Posté par  . Évalué à 2.

        dans mon ancien taff, qui avait besoin de windows pour certains outils de traitement,
        on avait installé cygwin,

        permettant d'avoir un shell 'linux like' avec les outils GNU comme bash, tail, awk, sed, perl, etc

        • [^] # Re: split, tail, head

          Posté par  . Évalué à 1.

          Neox, comme je l'avais dit une fois je ne sais pas si je t'avais aussi informer, je fais un stage et mes essais je le pratique sous Windows et quand je le remet a mon maitre de Stage il l'execute sous AIX. Chance que jusqu'ici tout fonctione sous Windows comme sous AIX, mais je sais une chose est que AIX est tres semblable a LINUX

          • [^] # Re: split, tail, head

            Posté par  . Évalué à 2.

            l'environnement importe peu (windows, linux, aix)
            le tout etant d'avoir les memes outils sur toutes ces machines.

            tail/head, grep, sed, perl sont des outils communs sur AIX ou Linux,
            ils sont rarement integrés par defaut sur windows,

            et comme ici tu es sur LINUXfr, on te donne des solutions pour des linuxiens,

            et donc on te propose d'installer Cygwin (une ligne de commande et des outils GNU sur ton windows) pour qu'il se comporte "comme un linux".

            sinon si ta machine est assez puissante, tu peux faire de la virtualisation (virtualbox par exemple) pour avoir un Linux à l'interieur de ton windows, tu pourras alors directement appliqué les commandes qu'on te donne, les adapter et les tester en reel.

            • [^] # Re: split, tail, head

              Posté par  . Évalué à 1.

              merci bien de l'explication. virtualbox c'est ce que mon maitre de stage me disait aussi ,j'espere que le prossessor Intel core i5 sera a la hauteur

              • [^] # Re: split, tail, head

                Posté par  . Évalué à 3.

                le core i5 ne posera pas de souci,
                par contre il te faut un peu de RAM, 4Go c'est peu mais suffisant, 8 c'est mieux.

        • [^] # Re: split, tail, head

          Posté par  (site web personnel) . Évalué à 2.

          dans mon ancien taff, qui avait besoin de windows pour certains outils de traitement, on avait installé cygwin,

          J'ai beaucoup utilisé Cygwin dans mon poste précédent et très franchement je ne suis même pas sûr que ce soit beaucoup plus rapide qu'une machine virtuelle VirtualBox – voire même pas plus rapide du tout si on utilise une machine virtuelle sans environnement graphique, en Headless avec connection SSH. Les avantages d'une machine virtuelle sont multiples: UNIX marche mieux, c'est plus facile d'avoir un environnement cohérent, la gestion des paquets est meilleure, etc.

          Cygwin était très pertinent avant la démocratisation des machines virtuelles, mais est-ce encore le cas aujourd'hui?

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.