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

  FORUM HardWare.fr
  Programmation
  Perl

  retrouver un mot dans un Fichier

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

retrouver un mot dans un Fichier

n°2256681
Henri772
Posté le 27-04-2015 à 13:26:25  profilanswer
 

Salut je suis un debutant en Perl et je n'ai pas encore de l'experience et j'ai besoin de votre aide.  
 j'ai un fichier contenant des results de traitement de d'autre Fichiers que j'aimerai un peu avoir un bon appercu, au fait dans mon Fichier il ya les resultats suivant:
 
default,primary,secondary,copy_directory,forced_copy_flag,always_allow_dump,type_of_dump,full_memory_dump,
 
d100spuptl25e0,/dev/lg_dumplv,/dev/sysdumpnull,/var/adm/ras,1,1,fault,disallow,
doc1,/del,/dev/null,/ras,1,0,fw-assisted,disallow,
doc2,/dev/lg_dumplv,/dev/sysdumpnull,//ras,1,1,fw,disallow,
doc3,/dev/lg_dumplv,/dev/sysdumpnull,/var/adm/ras,1,fault,fw-assisted,disallow,
doc4[/#FF1C00],5,fault,7,8,9,10,disallow,
 
en rouge ce sont les noms des fichiers, en noir ce sont des valeurs le premier fichier default ne doit pas etre pris en consideration,  seul les autres fichiers doivent etres traite
j'aimerai que les noms des fichier ayant la valeur "fault" me soit retourne, et ainsi que leur nombre. Dans la cas ici present le
resultat serait:
nombre de fichiers: 3
d100spuptl25e0
doc3
doc4
 

mood
Publicité
Posté le 27-04-2015 à 13:26:25  profilanswer
 

n°2256687
rat de com​bat
attention rongeur méchant!
Posté le 27-04-2015 à 14:32:29  profilanswer
 

Moi aussi je suis débutant, mon script fonctionne mais gilou (qui s'y connait très bien) aura peut-être des améliorations à proposer. J'ai mis quelque commentaires, si tu ne comprends pas demande moi!

Code :
  1. use strict; #il faut déclarer ses variables
  2. use warnings FATAL => 'all'; #stopper au moindre soucis
  3. use autodie; #stopper si problème sur les fichiers i/o
  4. open(INPUT, '<', 'fichier.txt');
  5. my $nombre=0;
  6. my @fichiers;
  7. while((my $ligne=<INPUT> ))
  8. {
  9.     next if($ligne=~/^\s+$/); #ignorer lignes vides ou contenant seulement des espaces
  10.     next if($ligne=~/^default/); #ignorer la ligne qui commence par "default"
  11.    
  12.     if($ligne=~/,fault,/) #si la ligne contient le mot "fault" entouré de virgules
  13.     {
  14.         $nombre++;
  15.         push @fichiers, (split(/,/, $ligne))[0]; #découper la ligne aux virgules et mettre le premier morceau dans @fichiers
  16.     }
  17. }
  18. close(INPUT);
  19. open(OUTPUT, '>', 'resultat.txt');
  20. print OUTPUT "nombre de fichiers: $nombre\n";
  21. print OUTPUT join("\n", @fichiers); #prendre le contenu de @fichiers, mettre un saut de ligne entre deux éléments et écrire le tout dans le fichier sortie
  22. close(OUTPUT);

Message cité 1 fois
Message édité par rat de combat le 27-04-2015 à 14:53:32
n°2256698
Henri772
Posté le 27-04-2015 à 15:26:16  profilanswer
 

Merci bien

n°2256745
gilou
Modérateur
Modzilla
Posté le 27-04-2015 à 20:41:28  profilanswer
 

rat de combat a écrit :

Moi aussi je suis débutant, mon script fonctionne mais gilou (qui s'y connait très bien) aura peut-être des améliorations à proposer.


C'est bien, j'aurais condensé un peu:

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5.  
  6. open(my $fhin, '<', 'fichier.txt');
  7. my @fichiers = ();
  8. while (<$fhin> ) {
  9.    push @fichiers, (split(/,/, $_))[0] if (/,fault,/);
  10. }
  11. close($fhin);
  12.  
  13. open(my $fhout, '>', 'resultat.txt');
  14. print $fhout "nombre de fichiers: ", 0+@fichiers, "\n";
  15. print $fhout "$_\n" foreach (@fichiers);
  16. close($fhout);


La seule différence essentielle est que je préfère des filehandle locaux, mais c'est juste une question de style.
 
A+,


Message édité par gilou le 27-04-2015 à 23:20:43

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2256746
Henri772
Posté le 27-04-2015 à 21:13:38  profilanswer
 

Gilou merci de ta proposition

n°2256747
gilou
Modérateur
Modzilla
Posté le 27-04-2015 à 22:19:04  profilanswer
 

Non, ça c'était juste pour répondre au rongeur combatif.
J'aurais procédé ainsi:

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5. use File::Grep qw( fgrep );
  6.  
  7. my @fichiers = fgrep { /,fault,/ } 'fichier.txt';
  8. open(my $fhout, '>', 'resultat.txt');
  9. print $fhout "nombre de fichiers: ", $fichiers[0]->{count}, "\n";
  10. foreach (sort keys %{$fichiers[0]->{matches}}) {
  11.  print $fhout +(split(/,/, $fichiers[0]->{matches}->{$_}))[0], "\n";
  12. }
  13. close $fhout;

:D  
J'aurais utilisé le module File::Grep, qui fait tout le boulot de parsing, et utilisé le fait qu'il retourne une structure qui contient toute l'info utile.
Sur ton exemple, fgrep retourne une liste dont le premier (et unique élément) est une référence sur un hash:
$fichiers[0] = {
          'count' => 3,
          'matches' => {
                         '6' => "doc3,/dev/lg_dumplv,/dev/sysdumpnull,/var/adm/ras,1,fault,fw-assisted,disallow,\n",
                         '3' => "d100spuptl25e0,/dev/lg_dumplv,/dev/sysdumpnull,/var/adm/ras,1,1,fault,disallow,\n",
                         '7' => "doc4,5,fault,7,8,9,10,disallow,\n"
                       },
          'filename' => 'aaz.txt'
        };
 
A+,


Message édité par gilou le 27-04-2015 à 23:20:05

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2256748
Henri772
Posté le 27-04-2015 à 22:43:05  profilanswer
 

je trouve ta premiere proposition, bonne pour la comprenhesion

n°2256750
gilou
Modérateur
Modzilla
Posté le 27-04-2015 à 23:15:00  profilanswer
 

C'est le principe de Perl: il n'y a pas UNE bonne solution, toute solution adaptée au niveau de celui qui l'utilise est bonne. :)
 
J'aurais pu écrire la mienne ainsi:

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5. use File::Grep qw( fgrep );
  6.  
  7. my @fichiers = fgrep { /,fault,/ } 'fichier.txt';
  8. open(my $fhout, '>', 'resultat.txt');
  9. print $fhout "nombre de fichiers: ", $fichiers[0]->{count}, "\n";
  10. print $fhout "$_\n" foreach (map {(split(/,/, $fichiers[0]->{matches}->{$_}))[0]} sort keys %{$fichiers[0]->{matches}});
  11. close($fhout);


 
Mais ça aurait été moins (ou pas) lisible a qui n'est pas un utilisateur avancé.
Le truc utile utilisé ici: si %hash est un hash, map {$hash{$_}} sort keys %hash; renvoie la liste des valeurs du hash, triées dans l'ordre des clés.
 
Tiens, une variante plus simple de mon premier post:

Code :
  1. #!/usr/bin/perl
  2. use strict;
  3. use warnings;
  4. use autodie;
  5.  
  6. open(my $fhin, '<', 'fichier.txt');
  7. my @fichiers = grep { /,fault,/ and s/,.*// } (<$fhin> );
  8. close($fhin);
  9.  
  10. open(my $fhout, '>', 'resultat.txt');
  11. print $fhout "nombre de fichiers: ", 0+@fichiers, "\n";
  12. print $fhout "$_" foreach (@fichiers);
  13. close($fhout);


 
Plutôt que de splitter en champs séparés par une virgule, et ne garder que le premier champ je vire tout ce qui après la première virgule (sauf le \n final). C'est probablement plus optimal.
j'aurais pu écrire map { s/,.*//; $_ } grep { /,fault,/ } à la place de grep { /,fault,/ and s/,.*// } pour faire plus pédagogique.
 
A+,


Message édité par gilou le 28-04-2015 à 03:34:14

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2256761
Henri772
Posté le 28-04-2015 à 10:58:21  profilanswer
 


 exactement ceci et vraiment plus simple,car je dois essaye de comprendre comment est ce que cela fonctionne merci bien

n°2256762
Henri772
Posté le 28-04-2015 à 11:02:27  profilanswer
 

mais dit pourquoi 0+@fichiers, le 0 qu'est ce que tu veus dire pas j'aurai imagine scalar @fichiers

mood
Publicité
Posté le 28-04-2015 à 11:02:27  profilanswer
 

n°2256765
Henri772
Posté le 28-04-2015 à 11:49:16  profilanswer
 

j'avais encore une question comme vous l'avez remarque le resultat du fichier suivant n'ai pas agreable a lire:
 
default,primary,secondary,copy_directory,forced_copy_flag,always_allow_dump,type_of_dump,full_memory_dump,
d100spuptl25e0,/dev/lg_dumplv,/dev/sysdumpnull,/var/adm/ras,1,1,fault,disallow,
doc1,/del,/dev/null,/ras,1,0,fw-assisted,disallow,
doc2,/dev/lg_dumplv,/dev/sysdumpnull,//ras,1,1,fw,disallow,
doc3,/dev/lg_dumplv,/dev/sysdumpnull,/var/adm/ras,1,fault,fw-assisted,disallow,
doc4[/#FF1C00],5,fault,7,8,9,10,disallow,  
 
j'aimerai savoir si il est possible en perl .d'ecrire un code capable d'ecrire cela dans une table html mais ce qui important de savoir est que le Tableau 6 lignes et 8 colonnes ceci peut toujours varie
du genre 4000 ligne et peut etre 200 colonnes. plus bas vous pouvez trouver mon code qui me donne ce resultat peut quelqu'un pourrai savoir ce qu'il faudrai que j'y ajoute. comme je l'ai mensionne le resultat je l'obtient comme en haut j'aimerai savoir si il est posible de l'avoir du genre comme ceci en desous.
 
 
default              primary              secondary              copy_directory     forced_copy_flag   always_allow_dump   type_of_dump   full_memory_dump  
d100spuptl25e0  /dev/lg_dumplv   /dev/sysdumpnull     /var/adm/ras        1                        1                            fault               disallow  
doc1                /del                   /dev/null                /ras                    1                        0                            fw-assisted      disallow  
doc2                /dev/lg_dumplv    /dev/sysdumpnull    //ras                   1                        1                            fw                  disallow  
doc3                /dev/lg_dumplv    /dev/sysdumpnull    /var/adm/ras        1                         fault                       fw-assisted      disallow  
doc4                5                       fault                     7                        8                        9                           10                   disallow  
 

Code :
  1. #!/usr/local/bin/perl
  2. use strict;
  3. use warnings;
  4. use XML::Twig;
  5. use Text::CSV;
  6. use Text::xSV;
  7. my $file1 = shift @ARGV;                                   
  8. my @files = glob '*.xml';                                   
  9. @files = grep { $_ ne $file1 } @files if defined $file1; 
  10. my $FileResult = 'result.csv'; 
  11. open( my $FhResult, '>', $FileResult )or die ("Unable to open file $FileResult\n$!" );
  12. my $twig1= XML::Twig->new(   
  13.         twig_handlers => { 
  14.                 'Parameter' => sub { 
  15.                         my $attr_name = $_->{'att'}->{'name'} // 'fault';   
  16.                     
  17.                                                       
  18.                         print $FhResult $attr_name . ",";   
  19.                 },
  20.         },
  21. );
  22. print $FhResult( (split('_', $file1,2))[0] . ',' ); 
  23. $twig1->parsefile($file1); 
  24. for my $file (@files) {
  25.     my $twig1 = XML::Twig->new(
  26.         twig_handlers => {
  27.             'Parameter' => sub {
  28.                 my $attr_value = $_->{'att'}->{'value'} // 'fault';   
  29.                 print $FhResult $attr_value . ",";
  30.             },
  31.         },
  32.     );
  33.     print $FhResult ( split( '_', "\n$file", 2 ) )[0] . ',';
  34.     $twig1->parsefile($file);                                     
  35. }
  36. close $FhResult;

n°2256766
gilou
Modérateur
Modzilla
Posté le 28-04-2015 à 11:51:40  profilanswer
 

Henri772 a écrit :

mais dit pourquoi 0+@fichiers, le 0 qu'est ce que tu veus dire pas j'aurai imagine scalar @fichiers

La variable @fichiers est une liste. Si j'appelle print dessus, ça va imprimer le contenu de la liste.
Je veux forcer une interprétation scalaire de la variable, ce qui me donnera son nombre d'éléments.
Je pourrais en effet utiliser l'opérateur unaire scalar de perl, et écrire scalar @fichiers, mais dans la pratique, on utilise souvent l'idiome 0+@fichiers, l'addition d'un nombre forçant l'interprétation scalaire de @fichiers. Je suppose que cette pratique provient des temps reculés ou l'opérateur scalar n'existait pas dans le langage.
J'aurais aussi pu faire $#fichiers + 1.
C'est juste une question d'habitude.
 
A+,


Message édité par gilou le 28-04-2015 à 11:52:16

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2256768
gilou
Modérateur
Modzilla
Posté le 28-04-2015 à 12:08:48  profilanswer
 

Henri772 a écrit :

j'aimerai savoir si il est possible en perl .d'ecrire un code capable d'ecrire cela dans une table html mais ce qui important de savoir est que le Tableau 6 lignes et 8 colonnes ceci peut toujours varie du genre 4000 ligne et peut etre 200 colonnes. plus bas vous pouvez trouver mon code qui me donne ce resultat peut quelqu'un pourrai savoir ce qu'il faudrai que j'y ajoute. comme je l'ai mensionne le resultat je l'obtient comme en haut j'aimerai savoir si il est posible de l'avoir du genre comme ceci en desous.

C'est pas très clair ton histoire.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2256769
Henri772
Posté le 28-04-2015 à 13:15:18  profilanswer
 

Gilou ilmalheureusement impossible des poste l'un des fichiers donc je possede sur le forum la tu allais faire la remaque que un Fichier en possede des milliers d'attributs value, et par ailleur si on parse un tel fichier, ceci n'ai pas agreable pour l'oeil de pouvoir lire le resultat car, il apparaitra des nombre et caractere separe de virgule.

n°2256771
gilou
Modérateur
Modzilla
Posté le 28-04-2015 à 13:40:41  profilanswer
 

CE qui n'est pas clair, c'est ce que tu veux obtenir au final.
Une table html? une fichier texte séparé par des tabulations? etc.
 
Si c'est pour une table html, je te suggère d'aller voir du côté de  HTML::Table::Compiler qui est très pratique pour remplir une table avec une liste de valeurs.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
n°2256917
rat de com​bat
attention rongeur méchant!
Posté le 29-04-2015 à 21:47:26  profilanswer
 

Merci gilou pour la relecture de mon code! Bien vu qu'il ne faut pas de variable en plus pour compter le nombre de fichiers. Et je note le coup du 0+@fichiers qui est plus court que scalar() que j'utilise habituellement.


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

  retrouver un mot dans un Fichier

 

Sujets relatifs
Liste fichier expression régulière[RESOLU] Batch - copier des parties d'un fichier texte
telechargement de fichier (ERREUR double En-têtes )genere un fichier via un fichier csv
html 5 drag and drop plusieurs fichiersuppression fichier avec macro VB
[PHP / JS] jquery file upload : retrouver nom du fichier uploadé ?[débutant] retrouver la ligne courante du fichier
Retrouver le nom d'un fichier avec un FILE*[Win32]Comment retrouver l'icône associée à une extension de fichier ?
Plus de sujets relatifs à : retrouver un mot dans un Fichier


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