Forum Programmation.perl Parsage sur plusieur fichier

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

Salut a tous,
j'ai un code me permetant le parsage d'un fichier mais j'aimerai qu'il soit la hauteur de me faire le parsage de disons par exemple 100 fichiers. quelqu'un pourrai m'aider. Merci. en voici mon code:

    use strict;
    use warnings;
    use XML::Twig;  

    my $file1 = $ARGV[0] || die 'No file1';    
    my $FileResult = $ARGV[3] || 'result.txt'; 

    open( my $FhResult, '>', $FileResult ) or die("Unable to open file $FileResult\n$!");

    my $twig1= XML::Twig->new(    
            twig_handlers => {    
                    'Parameter' => sub { 
                                    my $attr_value = $_->{'att'}->{'value'} || 'fault'; 
                                    print $FhResult $attr_name . ",";
                    },
            },
    );

    print $FhResult( (split('_', $file1,2))[0] . ',' ); 
    $twig1->parsefile($file1); 
end
  • # loop

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

    Tu rajoutes une bête loop et cela devrait faire l'affaire…

    for my $file (@ARGV) ....

    • [^] # Re: loop

      Posté par  . Évalué à -2.

      pourrais tu un peu etre precis avec ta Loop

      • [^] # Re: loop

        Posté par  (site web personnel, Mastodon) . Évalué à 3.

        quand tu appelles ton script perl, tu le fais avec :

        find . -name 'file*' -exec script.pl {} arg1 arg2 result.txt \;
        et voilà.

        Mais peut-être j'ai pas compris la question ou que t'as oublié de fournir des contraintes.

        • [^] # Re: loop

          Posté par  . Évalué à 1.

          Salut Mathieu
          quand j'appele mon script je le fait de la maniere suivante
          perl parser.pl default_sysdumpdev_150319.xml

          maintenant j'aimerai un bien insere une loop de maniere a ce que je puis appeler 1, 2, 3,…, n fichiers. c'est la que ce situe mon probleme

          • [^] # Re: loop

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

            Concrètement ils s'appellent comment exactement tes fichiers ?
            Sinon la commande marche bien si tu la comprend

          • [^] # Re: loop

            Posté par  . Évalué à 2.

            2 possibilités, qui vont dependre de la sortie attendue.

            1°) tu veux un fichier de sortie par fichier d'entrée => boucle du shell
            qui avec des fichiers A.xml, B.xml, C.xml
            va lancer 3 fois la commande perl parser.pl nom-du-fichier

            ta commande deviens alors :
            for file in *.xml;do perl parser.xml $file;done

            2°) avoir un seul fichier de sortie contenant le resultat de plusieurs fichiers XML => boucle dans ton perl, sur les arguments que tu lui donnes.
            tu vas alors lancé le programme comme suit :
            perl parser.pl A.xml B.xml C.xml

            et c'est dans le perl que tu fais une boucle pour lire chacun des arguments.

            • [^] # Re: loop

              Posté par  . Évalué à 1.

              j'aimerai que le fichier de sortie contient le resulat de plusieur XML-fichier
              c'est ce cette boucle for qui me menace actuellec'est a dire
              mes fichier sont quelque part sauvegarde sur mon disque C:
              1.xml. 2.xml, 3.xml, 4.xml,…, n.xml ainsi que mon parser.pl
              la quand je vais dans perl commandline je tape
              perl parser.pl 1.xml. 2.xml, 3.xml, 4.xml,…, n.xml
              et le resultat sur un fichier result.txt

              • [^] # Re: loop

                Posté par  . Évalué à 2. Dernière modification le 13 avril 2015 à 21:57.

                j'aimerai que le fichier de sortie contient le resulat de plusieur XML-fichier
                […]
                je tape

                perl parser.pl 1.xml. 2.xml, 3.xml, 4.xml,…, n.xml

                et le resultat sur un fichier result.txt

                donc ca marche ?

                • [^] # Re: loop

                  Posté par  . Évalué à 1.

                  Neox ca ne marche pas car la loop ne fonctione pas

                  • [^] # Re: loop

                    Posté par  . Évalué à 2.

                    donc si on reprend,

                    tu veux pouvoir taper :
                    perl parser.xml fichierA.xml fichierB.xml fichierC.xml
                    et que ca te sorte un seul fichier
                    resultat.txt

                    alors il faut faire la boucle dans le perl
                    pour lire chacun des argv

                    actuellement tu remplis $file1 avec le premier argument argv[0] avec le code my $file1 = $ARGV[0] || die 'No file1';

                    ben il te faut faire un boucle pour lire chacun des argv[1], argv[2], argv[3]… tant qu'il y en a en fait

                    d'ailleurs d'apres ton code, ton resultat se trouve en 4e position de la ligne de commande argv[3]
                    my $FileResult = $ARGV[3] || 'result.txt';

                    • [^] # Re: loop

                      Posté par  . Évalué à 1.

                      je vais essaye de voir cela demain, merci du cheminement

                      • [^] # Re: loop

                        Posté par  . Évalué à 1. Dernière modification le 14 avril 2015 à 13:35.

                        je sais pas si tu peus ecrire cette boucle ici , parceque la je ne m'en sort pas
                        j'ai ecris

                            my $file = $ARGV[1],$ARGV[2],$ARGV[3],... || die 'No file';    
                            for ($i = $ARGV[i], $i <= 3, $i++){
                            my $twig2= XML::Twig->new(    
                                twig_handlers => { 
                                        'Parameter' => sub { 
                        
                                                my $attr_value = $_->{'att'}->{'value'} || 'fault';  
                                                print $FhResult $attr_value . ",";
                                        },
                                },
                        );
                        
                        print $FhResult( (split('_', "\n$file",2))[0] . ',' ); 
                        $twig2->parsefile($file);

                        cela ne m'apporte rien ma faute se situe au niveau de mon for-loop car la j'ai deja cherche comment on effectue un for-loop avec plusieurs Arguments et aussi la premiere ligne de mon code a savoir

                        my $file = $ARGV[1],$ARGV[2],$ARGV[3],... || die 'No file';    
                        
                        • [^] # Re: loop

                          Posté par  . Évalué à 2.

                          peut-etre que c'est simplement parce que tu definis :

                          $file=$argv[1],$argv[2]…

                          qui ne te sert à rien,
                          puis que tu fais ta boucle avec $i avec $i qui va lire les arguments

                          mais que tu executes $twig2->parsefile($file)

                          dans la realité l'algo de ton code devrait ressembler à ca :

                          Pour Indice entre 1 et 3 {
                          lefichier = argument[$Indice]

                          traitement_du_fichier
                          }

                          • [^] # Re: loop

                            Posté par  . Évalué à 1. Dernière modification le 14 avril 2015 à 17:31.

                            regarde ce que je possede ilme signale une erreur a la ligne 12(a partir de for ) je ne comprend pas cette erreur

                            use strict;
                            use warnings;
                            use XML::Twig;
                            
                            my @files = @ARGV or die 'No files';
                            
                            my $FileResult = 'result.txt';
                            
                            open( my $FhResult, '>', $FileResult )
                              or die "Unable to open file $FileResult\n$!";
                            
                            for my $file (@files) {
                                my $twig1 = XML::Twig->new(
                                    twig_handlers => {
                                        'Parameter' => sub {
                                            my $attr_value = $_->{'att'}->{'value'} || 'fault';
                                            print $FhResult $attr_value . ",";
                                        },
                                    },
                                );
                            
                                print $FhResult ( split( '_', $file, 2 ) )[0] . ',';
                            
                                $twig1->parsefile($file);
                            }
                            
                            close $FhResult;

                            voila l'erreur que cela me notifie

                            mismatched tag at line 12, column 5, byte 629 at C:/strawberry/perl/site/lib/XML
                            /Parser.pm line 187.
                             at new.pl line 24.
                             at new.pl line 24.
                            
                            C:\Users\IBM_ADMIN\Documents>
                            • [^] # Re: loop

                              Posté par  . Évalué à 1.

                              maintenant j'ai essaye d#arranger mais juste quand il veut deja sortir de la boucle il me signale une erreur a ce niveau
                              $twig1->parsefile($file);

                            • [^] # Re: loop

                              Posté par  . Évalué à 1.

                              voila l'erreur que cela me notifie

                              mismatched tag at line 12, column 5, byte 629 at C:/strawberry/perl/site/lib/XML/Parser.pm line 187.

                              http://linuxfr.org/forums/programmation-perl/posts/xml-parser#comment-1596952

                              • [^] # Re: loop

                                Posté par  . Évalué à 1.

                                Nicolas c'est mon Fichier XML qui avait un probleme

                                • [^] # Re: loop

                                  Posté par  . Évalué à 1.

                                  le code etait bien , il y avait une erreur sur mon fichier XML, je voulais maintenant savoir si quelqu'un peut aider a modifier ce code de tel maniere que lors de l'execution il me retourne les attributs name du premier fichier et en ce qui concerne le reste de fichiers les attributs value , je doit souligne ici que le code plus haut me retourne les attributs value des fichiers.

                                  • [^] # Re: loop

                                    Posté par  . Évalué à 2.

                                    il va falloir adapter un peu,

                                    comme tu le dis toi meme le code renvoie actuellement la value
                                    et c'est logique avec

                                    my $attr_value = $_->{'att'}->{'value'} || 'fault';
                                    print $FhResult $attr_value . ",";

                                    si tu ne veux pas la value mais le name
                                    ben il suffit de changer cela

                                    et si tu veux la value ET le name,
                                    il faut faire 2 lignes pour creer $attr_value et $attr_name,
                                    puis les utiliser dans le print $FhResult

                                    • [^] # Re: loop

                                      Posté par  . Évalué à 1.

                                      Salut Neox je crois qu'on ne se comprend et meme avec cette petite erreur sur mon code ca fonctionait. mon probleme est qu'il me donne les attibuts value des fichiers que j'entre
                                      car egal ne nombre de Fichiers que j'entre il me retournera que les attributs value mais
                                      j'aimerai que pour le fichiers Nr.0 qu'il me retourne les Attributs name et le reste de fichiers les attributs value

                                      use strict;
                                      use warnings;
                                      use XML::Twig;
                                      
                                      my @files = @ARGV or die 'No files';
                                      
                                      my $FileResult = 'result.txt';
                                      
                                      open( my $FhResult, '>', $FileResult )
                                        or die "Unable to open file $FileResult\n$!";
                                      
                                      for my $file (@files) {
                                          my $twig1 = XML::Twig->new(
                                              twig_handlers => {
                                                  'Parameter' => sub {
                                                      my $attr_value = $_->{'att'}->{'value'} || 'fault';
                                                      print $FhResult $attr_value . ",";
                                                  },
                                              },
                                          );
                                      
                                          print $FhResult ( split( '_', $file, 2 ) )[0] . ',';
                                      
                                          $twig1->parsefile($file);
                                      }
                                      
                                      close $FhResult;
                                      • [^] # Re: loop

                                        Posté par  . Évalué à 2.

                                        faire du code implique de comprendre ce qu'il fait
                                        car copier coller sans comprendre, c'est prendre le risque d'installer un virus,
                                        et puis tu n'apprends rien si tu ne fais que copier/coller betement.

                                        ici tu as un code qui :
                                        - ouvre le fichier resultat,
                                        - fait une boucle pour traiter tous les fichiers passés en arguments
                                        - va prendre les valeurs (value) et les ecrire dans le fichier de resultat
                                        - ferme le fichier resultat

                                        qu'est ce qui t'empeche de faire une paragraphe similaire,
                                        que tu placerais AVANT de traiter TOUS les fichiers,
                                        qui va traiter le fichier ARGV[1] pour n'en prendre que les "NAME" ?

                                        • [^] # Re: loop

                                          Posté par  . Évalué à 1.

                                          Salut Neoxje vais te dire que tu es loin de savoir ce que tu racontes, tu tiens des propos donc tu ne peu pas prouver et je ne suis nom plus quelqu'un qui n'aime pas qu'on lui fasse des remarques,
                                          Comme tu pretant erte un si bon progmmeur tu aurais du ecrire ARGV[0] car la plupart de compiler et interpreteur compte commencant par 0 et non par 1. et c'est donc a ce niveau donc j'ai un probleme je ne sais pas comment ecrire mon code de maniere a qu'il commence a compte á 1 pour me donner les attributs value. car mon code devrait etre capable de traiter un grand nombre de fichier

                                          • [^] # Re: loop

                                            Posté par  . Évalué à 2.

                                            déssolé de t'avoir froissé,
                                            mais les explications precedentes donnent des schemas, des algorythmes et tu ne semble pas comprendre la "logique" qui se trouve derriere le code Perl que l'on t'a pondu plus haut (ou dans le post precedent).

                                            alors, oui, je me suis trompé d'un chiffre et j'ai mis ARGV[1] car pour moi (reflexe de bash et d'autres langages) ARGV[0] c'est le programme lui meme.
                                            bref, cela ne change rien à la logique, qui consiste à :

                                            • avant la boucle for, faire le meme traitement que celui existant mais uniquement sur le premier fichier (donc ARGV[0]), il suffit de changer value par name
                                            • garder la boucle actuelle qui fait le boulot que tu souhaites, à savoir sortir les values des fichiers xml pour les mettre dans $FhResult

                                            et si tu veux traiter 2000 fichiers, mais n'avoir toujours qu'un seul fichier de sortie,
                                            il faut regarder les $ARG disponibles, y en a surement un pour obtenir le nombre de fichiers.
                                            et donc faire ta boucle entre 0 et $Nombre-de-fichiers

                                            • [^] # Re: loop

                                              Posté par  . Évalué à 1.

                                              j'ai comme l'impression quenous ne nous comprenons pas du tout, voila tout mon code :

                                              use strict;
                                              use warnings;
                                              use XML::Twig;
                                              
                                              my $file_0 = $ARGV[0] or die 'No file1'; 
                                              my @files = @ARGV or die 'No files';
                                              
                                              my $FileResult = 'result.txt';
                                              open( my $FhResult, '>', $FileResult )or die ("Unable to open file `{mathjax} FileResult\n`!");
                                              
                                              
                                              my $twig1= XML::Twig->new(    
                                                      twig_handlers => {     
                                                              'Parameter' => sub { 
                                              
                                              
                                                                      my $attr_name = $_->{'att'}->{'name'} // 'fault'; 
                                                                      print $FhResult $attr_name . ",";
                                                              },
                                                      },
                                              );
                                              
                                              print $FhResult( (split('_', $file_0,2))[0] . ',' ); 
                                              $twig1->parsefile($file_0);
                                              
                                              
                                              for my $file (@files) {
                                                  my $twig1 = XML::Twig->new(
                                                      twig_handlers => {
                                                          'Parameter' => sub {
                                                              my $attr_value = $_->{'att'}->{'value'} // 'fault';
                                                              print $FhResult $attr_value . ",";
                                                          },
                                                      },
                                                  );

                                              print $FhResult ( split( '_', "\n$file", 2 ) )[0] . ',';
                                              $twig1->parsefile($file);
                                              }

                                              voila ce qu'il me donne a la sorti quand j'entre 4 fichiers a savoir:
                                              1- les attributs(name) fichier 0,
                                              2- les attributs(value) fichier 0,<-- ceci je n'aimerai pas l'avoir
                                              3- les attributs(value) fichier 1,
                                              4- les attributs(value) fichier 2,
                                              5- les attributs(value) fichier 4,

                                              default,primary,secondary,copy_directory,forced_copy_flag,always_allow_dump,type_of_dump,full_memo
                                              default,/dev/lg_dumplv,/dev/sysdumpnull,/var/adm/ras,1,0,fw-assisted,disallow,<-- ceci je n'aimerai pas l'avoir
                                              d100spuptl25e0,/dev/lg_dumplv,/dev/sysdumpnull,/var/adm/ras,1,1,fault,disallow,
                                              doc1,/dev/lg_dumplv,/dev/sysdumpnull,/var/adm/ras,1,0,fw-assisted,disallow,
                                              doc2,/dev/lg_dumplv,/dev/sysdumpnull,/var/adm/ras,1,1,fw-assisted,disallow,

                                              si cela apparait c'est parcequ'il traite le fichier Nr.0 2 fois une fois pour la sorti des attributs name et une seconde fois pour la sorti des attribut value alors que je ne veus pas cela pour la seconde fois et le problemese situe a la declaration de @file=@ARGV je ne sais pas comment l'empeche a ce qu'il ne me traite pas le fichier Nr.0 une fois de plus

                                              • [^] # Re: loop

                                                Posté par  . Évalué à 2.

                                                c'est deja un bon debut.

                                                pourquoi tu ne veux pas traiter les données du premier fichier ?

                                                bon en l'occurrence, il suffit de faire une boucle de 1 à la taille de $ARGV
                                                plutot qu'un parcours du tableau @files qui contient TOUS les fichiers.

                                                ou un peu plus sale, dans la boucle for,
                                                lui dire de sauter le fichier si $file = $ARGV[0]

                                                • [^] # Re: loop

                                                  Posté par  . Évalué à 1.

                                                  j'ai deja fouille mais je n'arrive pas a trouver des information concernant le saut dans un tableau

                                              • [^] # Re: loop

                                                Posté par  . Évalué à 1.

                                                je ne sais pas comment l'empeche a ce qu'il ne me traite pas le fichier Nr.0 une fois de plus

                                                shift est ton ami. Du coup, ton code deviendrait :

                                                my $file_0 = shift or die 'No file1'; 
                                                my @files = @ARGV or die 'No files';

                                                Le shift enlève le premier argument après l'avoir affecté à ta variable $file_0 ; du coup, tu ne la retrouves plus ultérieurement dans @ARGV.

                                                • [^] # Re: loop

                                                  Posté par  . Évalué à 1.

                                                  Merci bien c'etait pourtant tres simple, j'ai fouille mais je ne suis pas tombe decu.
                                                  je te remerci infiniment

                                                  • [^] # Re: loop

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

                                                    A mon avis, pour avoir réagit en premier, je pense qu'il serait bien et temps de prendre un bouquin sur Perl ;-)

                                                    • [^] # Re: loop

                                                      Posté par  . Évalué à 1.

                                                      voila le boucin donc je possede, il faut aussi que je mensione que je suis entrain d'apprendre perl
                                                      De Larry Wall, Tom Christiansen et Jon Orwant

                                                      • [^] # Re: loop

                                                        Posté par  . Évalué à 1.

                                                        Salut
                                                        je desire une fois de plus votre aide,
                                                        j'ai un Code-Perl qui fonctione sur plusieurs fichiers-XML, mais pour cela je dois donner sur mon editor-perl la commande c: perl code.pl A.xml B.xml C.xml D.xml et j'obtient un resultat, comment faire si je met le tout dans un Odneur avec un millie de fichier-XML et j'aimerai que le code soit a mesure de traiter les fichiers-XML tout seul, sans toute fois donner tous les noms de mes fichiers-XML.

                                                        • [^] # Re: loop

                                                          Posté par  . Évalué à 2.

                                                          si ton code sait géré A.xml B.xml C.xml….
                                                          et que tu ne le limites pas toi meme à 4 ou 5 arguments,

                                                          tu dois pouvoir le lancer avec perl code.pl *.xml

Suivre le flux des commentaires

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