IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

Recherche dans un fichier impossible enregistré dans un fichier


Sujet :

Langage Perl

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Novembre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Novembre 2014
    Messages : 18
    Points : 9
    Points
    9
    Par défaut Recherche dans un fichier impossible enregistré dans un fichier
    Bonjour à tous,

    je fais un script qui dois recherché dans les fichiers d'un dossier et ses sous dossiers le contenu qui correspond a ce que l'utilisateur cherche.
    J'ai déjà fais un script qui fonctionne le problème c'est qu'il marche comme ca :

    (au préalable je demande le dossier)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    print "Veuillez entrer le message d'erreur que vous voulez rechercher : ";
    chomp(my $exp = <STDIN>);
    sub recherche {;
      if (-f){
        print "**** FICHIER CONTENANT UNE ERREUR ****\n
        $File::Find::dir/$_\n"
        if grep { /$exp/ } `cat $_`; 
      }
    }

    Mon problème ici est le grep puis l'affichage via un cat, j'aimerais que ca s'enregistre dans un fichier .Txt directement (qui n'existe pas)

    je ne sais pas comment faire ? j'ai essayé avec un print mais K.O


    Merci de votre aide

  2. #2
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je crois qu'il manque ceci à la fin du script :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    find(\&recherche,"$path");
    Pour remplacer le `cat $_`, il faut :
    - ouvrir le fichier $_ : open my $F, "<", $_;
    - effectuer le grep sur la lecture de son contenu : print "ERROR found" if grep /$exp/, <$F>;

    Cela dit, une chaine de caractère lue au clavier ne devrait pas être utilisée "telle quelle" comme expression régulière. Par exemple, si l'utilisateur tape un ".", celui-ci sera interprété comme "n'importe quel caractère". Si c'est bien ce qui est désiré, alors pas de soucis, sinon, utiliser la fonction quotemeta.

    Enfin, s'il s'agit d'une recherche d'une simple chaine, sans besoin d'expression régulière, il est préférable d'utiliser la fonction index qui retourne un indice de sous-chaine dans une chaine, ou -1 en cas d'échec.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Novembre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Novembre 2014
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Oui le code y était bien :p

    mon code actuel complet est :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #!/usr/bin/perl
    use strict;
    use warnings;
    use File::Find;
     
    print "Veuillez entrer le chemin du dossier : ";
    chomp(my $path = <STDIN>);
     
     
    #Le chemin du fichier config.cfg est passé en paramètre par l'utilisateur
    print "Veuillez entrer le message d'erreur que vous voulez rechercher : ";
    chomp(my $exp = <STDIN>);
    print "Fichier(s) contenant le mot '$exp':\n";
     
    sub recherche {;
      if (-f){
        print  "$File::Find::dir/$_\n"
        if grep { /$exp/ } `cat $_`;
     
     
      }
    }
     
    find(\&recherche,"$path");
    print "*** Recherche terminee ***";
    __END__

    Oui le code ne dois pas être parfait et meme si l'utilisateur tape "." cela recherchera.
    Par contre je comprend pas très bien ce que tu m'explique et comment l'appliqué surtout.
    Je cherche a enregistrer dans un fichier .txt

  4. #4
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Je t'ai montré comment écrire le résultat, donc lorsque tu lances le script tu peux simplement le faire en précisant que le résultat doit aller dans un fichier texte :
    perl script.pl >resultat.txt

    Si tu tiens à écrire le fichier directement depuis le script, ouvre alors un fichier en écriture en début de script, et utilise le File Handle pour écrire ton résultat (le print "ERROR found" notamment).

    Écris ce que tu penses avoir compris et montre nous le résultat.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  5. #5
    Futur Membre du Club
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Novembre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Novembre 2014
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Ca fonctionne pas mais j'ai pas d'erreur j'ai peut être mal compris

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #!/usr/bin/perl
    use strict;
    use warnings;
    use File::Find;
     
    print "Veuillez entrer le chemin du dossier : ";
    chomp(my $path = <STDIN>);
     
     
    #Le chemin du fichier config.cfg est passé en paramètre par l'utilisateur
    print "Veuillez entrer le message d'erreur que vous voulez rechercher : ";
    chomp(my $exp = <STDIN>);
    print "Fichier(s) contenant le mot '$exp':\n";
    my $F="resultat.txt";
    sub recherche {;
      if (-f){
        print  "$File::Find::dir/$_\n"
        if grep { /$exp/ } `cat $_`;
        open my $F, ">>", $_;
        print "ERREUR found" if grep /$exp/, <$F>;
     
      }
    }
     
    find(\&recherche,"$path");
    print "*** Recherche terminee ***";
    __END__
    Donc la j'ai déclaré le $F en résultat.txt après mon grep j'ouvre mon $F et j'ajoute avec ">>" le contenu de $_
    Vu que ca fonctionne pas j'ai du très mal comprendre ?

  6. #6
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Là, tu confonds le file handle du fichier dans lequel tu fais une recherche (avec grep), qui doit être ouvert EN LECTURE (et non en écriture comme tu l'as fait, ce qui risque de t'effacer tous tes fichiers), et le handle du fichier de sortie, qu'il faut ouvrir en écriture une seule fois avant l'appel à la fonction find.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  7. #7
    Futur Membre du Club
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Novembre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Novembre 2014
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Je suis carrément perdu..

    ca donnerai ca ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    print "Veuillez entrer le message d'erreur que vous voulez rechercher : ";
    chomp(my $exp = <STDIN>);
    print "Fichier(s) contenant le mot '$exp':\n";
    my $F="resultat.txt";
    sub recherche {;
      if (-f){
        print  "$File::Find::dir/$_\n"
        if grep { /$exp/ } `cat $_`;
        open my $F, "<", $_;
        print "ERREUR found" if grep /$exp/, <$F>;
     
      }
    }
    open $F, ">", $_;
    find(\&recherche,"$path");
    print "*** Recherche terminee ***";
    __END__

  8. #8
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Voici les changements minimaux à faire pour que ça marche (lignes 11 et 15), mais il faut peut-être encore corriger des choses que je n'ai peut-être pas vues, et je ne peux tester maintenant.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
          print "Veuillez entrer le message d'erreur que vous voulez rechercher : ";
            chomp(my $exp = <STDIN>);
            print "Fichier(s) contenant le mot '$exp':\n";
            my $F="resultat.txt";
            sub recherche {;
              if (-f){
                print  "$File::Find::dir/$_\n"
                if grep { /$exp/ } `cat $_`;
                open my $F, "<", $_;
                print $FH_ERR "ERREUR found" if grep /$exp/;
     
              }
            }
            open my $FH_ERR, ">", $F or die "ouverture impossible de $F $!";
            find(\&recherche,"$path");
            print "*** Recherche terminee ***";
    En fait, je serais tenté de réécrire beaucoup plus, pour faire du bon code, mais pas le temps tout de suite. J'essaierai de repasser plus tard.

  9. #9
    Futur Membre du Club
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Novembre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Novembre 2014
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Merci beaucoup pour la réponse.

    Le code a un problème au niveau de la ligne print $FH_ERR "ERREUR found" if grep /$exp/;

    Du coup mon fichier résultat.txt se crée bien mais est vide.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #!/usr/bin/perl
    use strict;
    use warnings;
    use File::Find;
     
    print "Veuillez entrer le chemin du dossier : ";
    chomp(my $path = <STDIN>);
     
     
    #Le chemin du fichier config.cfg est passé en paramètre par l'utilisateur
    print "Veuillez entrer le message d'erreur que vous voulez rechercher : ";
            chomp(my $exp = <STDIN>);
            print "Fichier(s) contenant le mot '$exp':\n";
            my $F="resultat.txt";
            sub recherche {;
              if (-f){
                print  "$File::Find::dir/$_\n"
                if grep { /$exp/ } `cat $_`;
                open my $F, "<", $_;
                print $FH_ERR "ERREUR found" if grep /$exp/;
     
              }
            }
            open my $FH_ERR, ">>", $F or die "ouverture impossible de $F $!";
            find(\&recherche,"$path");
            print "*** Recherche terminee ***";

  10. #10
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    La logique de ce que tu as dans ton if est viciée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
                print  "$File::Find::dir/$_\n"
                if grep { /$exp/ } `cat $_`;
                open my $F, "<", $_;
                print $FH_ERR "ERREUR found" if grep /$exp/;
    Tu ouvres le fichier, mais tu ne le lis pas, donc il ne se passe rien. Et puis enlève cette ligne avec le cat, fais les choses en Perl, pas en Shell quand c'est possible.

    Essaie ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
                print  "$File::Find::dir/$_\n"; 
                open my $F, "<", $_ or die "ouverture impossible de $_ $!";
                while (my $ligne = <$F>) {
                     print $FH_ERR "ERREUR found" if $ligne =~ /$exp/;
                }

  11. #11
    Futur Membre du Club
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Novembre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Novembre 2014
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Oui mais je n'ai jamais pratiqué la gestion des fichiers en perl..

    sinon le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    #!/usr/bin/perl
    use strict;
    use warnings;
    use File::Find;
     
    print "Veuillez entrer le chemin du dossier : ";
    chomp(my $path = <STDIN>);
    my $FH_ERR;
     
    print "Veuillez entrer le message d'erreur que vous voulez rechercher : ";
            chomp(my $exp = <STDIN>);
            print "Fichier(s) contenant le mot '$exp':\n";
            my $F="resultat.txt";
            sub recherche {;
              if (-f){
              print  "$File::Find::dir/$_\n";
     
                open my $F, "<", $_ or die "ouverture impossible de $_ $!";
                while (my $ligne = <$F>) {
                print $FH_ERR "ERREUR found" if $ligne =~/$exp/;
                }
            }
            }
            open my $FH_ERR, ">", $F or die "ouverture impossible de $F $!";
            find(\&recherche,"$path");
            print "*** Recherche terminee ***";
    Me retourne : Can't use an undefined value as a symbol reference at /Users/Macbook/Desktop/test/test.pl line 20, <$F> line 1.

  12. #12
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Bonsoir,

    Oui mais je n'ai jamais pratiqué la gestion des fichiers en perl.
    Ce n'est aucunement une critique personnelle de ma part, je te dis juste ce qui ne va pas dans ton code, et pourquoi.

    Après, franchement, j'ai un peu de mal à comprendre ton code parce que tu n'as pas la discipline de le formater (indentation) rigoureusement. Je peux te garantir de ma longue expérience que beaucoup de rigueur dans la gestion de l'indentation te fera gagner un temps fou par la suite. Ne néglige jamais cela.

    Ensuite, indépendamment de l'erreur que tu as à l'exécution, il y a un problème majeur dans ton code: tu utilises la variable $F pour deux choses complètement différentes: le nom du fichier de sortie et le file handle du fichier en entrée. Je te conseille vraiment de prendre des noms de variables un peu plus longs (pas forcément très longs, mais un peu plus) et surtout plus parlants. Cela t'évitera de te mélanger les pinceaux.

    Je suis rentré très tard d'une réunion ce soir, et n'ai pas le temps maintenant de revoir tout ton programme. Je te propose une version plus simple prenant un seul fichier en entrée et écrivant dans un fichier en sortie, et conforme au "bonnes pratiques" communément admises par la communauté Perl.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    use strict;
    use warnings;
     
    my $file_in = "fichier_entree.txt";
    open my $FH_IN, "<", $file_in or die "Impossible d'ouvrir le fichier en entrée $file_in $!";
     
    my $file_out = "fichier_sortie.txt";
    open my $FH_OUT, ">", $file_out or die "Impossible d'ouvrir le fichier en sortie $file_out $!";
     
    while (my $ligne = <$FH_IN>) {
         print $FH_OUT "Erreur sur la ligne suivante : $ligne" if $ligne =~ /ERROR/;
    }
    close $_ for ($FH_IN, $FH_OUT);
    J'espère que cela te donne un bon exemple à modifier selon tes besoins et à utiliser.

    Sur l'erreur d'exécution que tu as, il faudrait que tu dises quelle est précisément la ligne 20 dans le fichier de ton script. Là, comme cela, pas assez d'information, je n'arrive pas à identifier la source de l'erreur.

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Novembre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Novembre 2014
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Merci beaucoup de ta réponse, je la prend en note.
    C'est vrai que la j'essai plus de faire dans la bidouille que dans la perfection.

    Merci encore de prendre sur ton temps libre pour m'apportée une réponse.

    Le code que tu me propose est simple et clair (je le comprend) néanmoins je cherche vraiment le fonctionnement initial.
    la ligne 20 correspond bien a la ligne 20 de l'inséré du code soit :

    print $FH_ERR "ERREUR found" if $ligne =~/$exp/;


    Je n'ai pas de fichier d'entrée par contre et je n'en souhaite pas, je voudrais que l'analyse se face dans le dossier indiqué lors de la saisie et les sous dossier (-f)

  14. #14
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    J'ai bien compris que tu voulais parcourir un répertoire récursivement. J'ai juste illustré comment ouvrir un fichier en lecture et un autre fichier en écriture.

    Il me semble, d'après ce que tu dis, que tu arrives à ouvrir le fichier en écriture (ce qui doit être fait une seule fois). Il te suffit maintenant de mettre l'ouverture du fichier en lecture dans la boucle parcourant le répertoire pour avoir le résultat voulu. Comme je l'ai dit, le problème majeur que je voyais dans ton code ayant l'erreur signalée était l'utilisation de $F pour désigner deux choses complètement différentes (un nom de fichier d'un côté et un file handle de l'autre). Corrige déjà cela, ensuite on verra.

  15. #15
    Expert confirmé

    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2009
    Messages
    3 577
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Bas Rhin (Alsace)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2009
    Messages : 3 577
    Points : 5 753
    Points
    5 753
    Par défaut
    Citation Envoyé par cdjkhdjlhxjklnjskznj Voir le message
    Je suis carrément perdu..

    ca donnerai ca ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    print "Veuillez entrer le message d'erreur que vous voulez rechercher : ";
    chomp(my $exp = <STDIN>);
    print "Fichier(s) contenant le mot '$exp':\n";
    my $F="resultat.txt";
    sub recherche {;
      if (-f){
        print  "$File::Find::dir/$_\n"
        if grep { /$exp/ } `cat $_`;
        open my $F, "<", $_;
        print "ERREUR found" if grep /$exp/, <$F>;
     
      }
    }
    open $F, ">", $_;
    find(\&recherche,"$path");
    print "*** Recherche terminee ***";
    __END__
    Je repars de cette version de ton script, qui partait d'une bonne base à mes yeux. Voila ce qui va :
    - le print "ERREUR found" if grep /$exp/, <$F>; est bien écrit, il cherche toutes les lignes contenant $exp dans $F et affiche "ERREUR found" pour chacune (on peut améliorer ceci plus tard).
    Maintenant, ce qui ne va pas :
    - tu utilises $F pour 3 choses différentes : le nom du fichier texte de sortie, le handle des fichiers à lire, et le handle du fichier de sortie. Séparer ces trois données dans des variables différentes : $F pour le handle des fichiers à lire, $f_out pour le nom du fichier de sortie et $F_OUT pour le handle de fichier de sortie
    - tu ouvres le fichier de sortie avec l'instruction open $F, ">", $_;, mais $_ n'est pas défini (cela devrait être $f_out), et tu souhaites l'utiliser dans la fonction recherche, qui elle, est définie avant. Tu dois donc déplacer au minimum la déclaration de $F_OUT AVANT la fonction recherche (et pourquoi pas, ouvrir le fichier à ce moment là : open my $F_OUT, ">", $f_out or die "Can't open $f_out: $!";)
    - tu as laissé la ligne if grep { /$exp/ } `cat $_`; qui, outre le fait qu'elle n'est plus utile, conditionne l'apparition du print précédent dont tu as enlevé le ; à la fin, sans doute pour corriger une erreur de syntaxe) : tu dois supprimer cette ligne et restaurer le ; après le print "$File::Find::dir/$_\n"
    - tu écris "ERREUR found" sur STDOUT, alors que tu voudrais le faire dans $F_OUT, écris donc ton print ainsi : print { $F_OUT } "ERREU...

    Voila au moins tous ces points à corriger.
    Plus j'apprends, et plus je mesure mon ignorance (philou67430)
    Toute technologie suffisamment avancée est indiscernable d'un script Perl (Llama book)
    Partagez vos problèmes pour que l'on partage ensemble nos solutions : je ne réponds pas aux questions techniques par message privé
    Si c'est utile, say

  16. #16
    Futur Membre du Club
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Novembre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Novembre 2014
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Bonjour,

    J'avais mis un peu ca de côté mais me revoilà (j'ai un réel besoin dans mon quotidien)

    Alors voila mon code actuel je pense que j'ai compris le principe.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
     
    #!/usr/bin/perl
    use strict;use warnings;
    use File::Find;
     
    print "Veuillez entrer le chemin du dossier : ";
    chomp(my $path = <STDIN>);
    open (fichierSortie, "> fichiersortie.txt");
     
    print "Veuillez entrer le message d'erreur que vous voulez rechercher : ";
    chomp(my $exp = <STDIN>);
     
    sub recherche {
     
      if(-f $_ =~ /ai/){
    		print (fichierSortie "$_");
    		}
    	}
     
    find(\&recherche,"$path");
    __END__
    Mon code actuel me crée bien le fichier .txt de sortie mais rien dedans (pas d'erreur lors de la compilation) je comprend pas trop ?

    Je rappel mon impératif : Il faut que ca cherche dans un dossier et ses sous-dossiers tous les fichiers qui contienne le contenu de la variable $exp et écrire dans un fichier de sortie la liste des fichiers répondant au critère.


    Merci de vos retours.

  17. #17
    Membre chevronné Avatar de dmganges
    Homme Profil pro
    Retraité. Ne recherche pas un emploi.
    Inscrit en
    Septembre 2011
    Messages
    1 392
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Retraité. Ne recherche pas un emploi.
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2011
    Messages : 1 392
    Points : 2 044
    Points
    2 044
    Par défaut
    Bonjour,

    Si ça te dis, tu peux t'inspirer de recherche.pl :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    #!/usr/bin/perl
    use warnings;
    use strict;
    use utf8;
    use Tk;
    use Tk::LabFrame;
    use Tk::ROText;
    use File::Spec;														# Permet une meilleure gestion des noms des chemins sous tous les OS
    use File::Path;														# Gestion des répertoires
    my $RepBas = 'E:/';
    my $Directory = $RepBas;
    my $LabRepertoire = $RepBas;
    my $LabRecursif = "Récursivité désactivée";
    my $LabFic = "";
    my $LabMessage = "";
    my $Trouve = 0;
    my $Stop = "";
    my $IN = ();
    my $IN_Fic = "";
     
    ActiverAccentsDOS();
     
    my $fen  = MainWindow->new;
    my $width = $fen->screenwidth();
    my $height = $fen->screenheight();
    $fen->destroy();
     
    # Creation du widget principal
    my $Wm = MainWindow->new(
    	-width			=> $width,
    	-height			=> $height,
    	-title      => "Spinoza",
      -background => 'white',
    );
     
    $width = $Wm->screenwidth*(4/5);
    $height = $Wm->screenheight*(4/5);
    $Wm->configure(-height=>$height, -width=>$width, -title=>"Recherche dans un fichier");
    $Wm->geometry( $width ."x". $height );
    $Wm->MoveToplevelWindow (100,100);
    #$Wm->overrideredirect(1);
    #$Wm->packPropagate(0);
    #$Wm->raise();
     
    ###############################
    # Scrolled qui affiche le texte
    my $widget_texte = $Wm->Scrolled(
      'ROText',
      -scrollbars => 'e',
      -takefocus  => 0,
      -wrap      => 'word',
      -relief    => 'flat',
      -background => '#ABFAA3',
    );
    configurer_tags($widget_texte);
     
    # Cadre des configurations
    my $couleur_commune = '#E0F0FF';
    my $cadre_configuration_playlist = $Wm->Frame( -background => $couleur_commune, );
     
    # Cadre Gestion
    my $cadre_gestion = $Wm->LabFrame(
      -label      => 'Gestion',
      -background => $couleur_commune,
      -font      => '{Simplified Arabic} 10 {bold}',
    );
     
    # Choix du répertoire
    my $Repertoire = $cadre_gestion->Button(
    	-text => "Choix du répertoire",
    	-command => sub {
    		# Selectionner un répertoire
    		$Directory = $Wm->chooseDirectory(
    			-title      => "Selection d'un répertoire",
    			-initialdir => $Directory,
    		);
    		if ( $Directory) {
    			$LabRepertoire = $Directory;
    			$Wm->update();
    		}
    	},
    );
     
    # Cases à cocher pour récursivité
    my $Recursif = 0;
    my $CasRecurv = $cadre_gestion->Checkbutton (
    	-text => "Récusivité",
    	-variable => \$Recursif,
    	-command => sub {
    		if ( $Recursif == 0 ) {
    			$LabRecursif = "Récursivité désactivée";
    		} else {
    			$LabRecursif = "Récursivité activée";
    		} 
    	},
    );
     
    # Pattern Nom fichier
    my $PatternFic = ".*";
    my $LabelPatternFic = $cadre_gestion->Label(
    	-text => "Fichier",
    	-font => '{Simplified Arabic} 10 {bold}',
    );
     
    my $PatternFicSaisie = $cadre_gestion->Entry(
    	-width				=> 30,
    	-justify			=> 'left',
    	-textvariable	=> \$PatternFic,
    	-font					=> '{Simplified Arabic} 10 {bold}',
    );
     
    # Pattern Extension
    my $PatternExt = ".*txt";
    my $LabelPatternExt = $cadre_gestion->Label(
    	-text => "Extension",
    	-font => '{Simplified Arabic} 10 {bold}',
    );
     
    my $PatternExtSaisie = $cadre_gestion->Entry(
    	-width				=> 5,
    	-justify			=> 'left',
    	-textvariable	=> \$PatternExt,
    	-font					=> '{Simplified Arabic} 10 {bold}',
    );
     
    # Pattern Recherche Avec
    my $PatternRechAvec = "";
    my $LabelPatternRechAvec = $cadre_gestion->Label(
    	-text => "Avec",
    	-font => '{Simplified Arabic} 10 {bold}',
    );
     
    my $PatternRechercheAvec = $cadre_gestion->Entry(
    	-width				=> 40,
    	-justify			=> 'left',
    	-textvariable	=> \$PatternRechAvec,
    	-font					=> '{Simplified Arabic} 10 {bold}',
    );
     
    # Pattern Recherche Sans
    my $PatternRechSans = "";
    my $LabelPatternRechSans = $cadre_gestion->Label(
    	-text => "Sans",
    	-font => '{Simplified Arabic} 10 {bold}',
    );
     
    my $PatternRechercheSans = $cadre_gestion->Entry(
    	-width				=> 40,
    	-justify			=> 'left',
    	-textvariable	=> \$PatternRechSans,
    	-font					=> '{Simplified Arabic} 10 {bold}',
    );
     
    # Start
    my $bouton_start = $cadre_gestion->Button(
    	-text    => "Start",
    	-command => sub {
    		$Trouve = 0;
    		$LabRepertoire = $Directory;
    		$LabFic = "";
    		$LabMessage = "Recherche en cours...";
    		$widget_texte->delete( '1.0', 'end' );
    		$Wm->update;
    		ListerFichiers($Directory, $Recursif);
    		$LabMessage = "Recherche terminée : TROUVÉ = $Trouve";
    	},
    );
     
    # Stop
    my $bouton_stop = $cadre_gestion->Button(
    	-text    => "Stop",
    	-command => [ \&stop, ],
    );
     
    # Exit
    my $bouton_exit = $cadre_gestion->Button(
    	-text    => "Exit",
    	-command => [ \&fermer, ],
    );
     
    ####################################
    # Cadre pour les messages de service
    my $cadre_messages = $Wm->Frame( -background => $couleur_commune, );
     
    # Label qui affichera le répertoire courant
    my $label_repertoire = $cadre_messages->Label(
      -textvariable => \$LabRepertoire,
      -width => 15,
      -background  => '#FFE0D0',
      -relief      => 'groove',
    );
     
    # Label qui affichera l'info récursivité
    my $label_recursif = $cadre_messages->Label(
      -textvariable => \$LabRecursif,
      -width => 20,
      -background  => '#FFE0D0',
      -relief      => 'groove',
    );
     
    # Label qui affichera le fichier en cours
    my $label_fic = $cadre_messages->Label(
      -textvariable => \$LabFic,
      -width => 5,
      -background  => '#FFE0D0',
      -relief      => 'groove',
    );
     
    # Label qui affichera les messages, en bas
    my $label_message = $cadre_messages->Label(
      -textvariable => \$LabMessage,
      -background  => '#FFE0D0',
      -relief      => 'groove',
    );
     
    ####################################
    # Gestion de l'affichage des widgets
    #
    $cadre_messages->pack(qw / -side bottom -fill both -expand 0 /);
    $label_repertoire->pack(qw / -side left -fill both -expand 1 /);
    $label_recursif->pack(qw / -side left -fill both -expand 0 /);
    $label_fic->pack(qw / -side left -fill both -expand 1 /);
    $label_message->pack(qw / -side left -fill both -expand 1 /);
     
    $widget_texte->pack(qw / -side bottom -fill both -expand 1 /);
     
    $cadre_gestion->pack(qw / -side right -fill both -expand 1 /);
     
    $Repertoire->grid(  $CasRecurv, $LabelPatternFic, $PatternFicSaisie, $PatternExtSaisie, $LabelPatternExt, $LabelPatternRechAvec, $PatternRechercheAvec,
    										$PatternRechercheSans, $LabelPatternRechSans, $bouton_start, $bouton_stop, $bouton_exit,
    	qw / -padx 2 -pady 5 -sticky nsew /
    );
     
    MainLoop;
     
    #############################################################################
     
    #============================================================================
    # Nombre d'arguments : 1 ou 2
    # Argument(s)        : un répertoire et valeur 0 ou 1 (récursivité)
    # Retourne           : Tableau de fichier (@fichiers)
    # Origine = http://perl.developpez.com/faq/perl/?page=section1#ListerFichiers
    #============================================================================
    sub ListerFichiers {
    	my ( $repertoire, $recursivite ) = @_;
    	if ( ( not defined $recursivite ) || ( $recursivite != 1 ) ) { $recursivite = 0; }
    	opendir (my $FhRep, $repertoire)
    		or warn "impossible d'ouvrir le répertoire $repertoire\n" and $LabMessage = "Ouverture impossible $repertoire - $! - $@" and return;
    	# Liste fichiers et répertoire sauf (. et ..)
    	my @Contenu = grep { !/^\.\.?$/ } readdir($FhRep);
    	closedir ($FhRep);
     
    	# On récupère tous les fichiers
    	my @fichiers;
    	foreach my $nom ( sort @Contenu ) {
    		last if ($Stop ne "");
    		# Fichiers
    		if ( -f "$repertoire/$nom") {
    			my ($Fic, $Ext) = split (/\./,$nom);
    		#	print "FIC=$Fic == EXT=$Ext  PATTERNFIC=$PatternFic PATTERNEXT=$PatternExt\n";
    			next if ($Fic !~ /$PatternFic/ );
     
    			next if (!$Ext);
     
    			next if ($Ext eq "mp3" );
    			next if ($Ext eq "mp4" );
    			next if ($Ext eq "wav" );
    			next if ($Ext eq "jpg" );
    			next if ($Ext eq "bmp" );
     
    			next if ($Ext !~ /$PatternExt/ );
     
    			push ( @fichiers, "$repertoire/$nom" );
    			$LabRepertoire = "$repertoire/$nom";
    			$IN_Fic  = "$repertoire/$nom";
    			$LabFic  = "$repertoire/$nom";
     
    			my $Encodage = `file "$IN_Fic"`;
    			my $Codage   = '';
    			$Codage      = 'utf8' if ( $Encodage =~ 'UTF-8' );			#	$Codage      = ''     if ( $Encodage =~ 'ISO-8859' );
     
    			unless (open ($IN, "<:".$Codage, $IN_Fic)) {
    				$LabMessage = "ERREUR : Impossible d'ouvrir $IN_Fic - ENCODAGE=$Codage $! - $@\n";
    				$Wm->Label->update();
    				return;
    			}
    			my $NumLigne = 0;
    			my $Flag = 0;
    			while ( my $Ligne = <$IN> ) {
    				$NumLigne++;
    				next if ($Ligne !~ /$PatternRechAvec/ );
    				next if ($PatternRechSans && $Ligne =~ /$PatternRechSans/ );
    				$widget_texte->insert( 'end', "\n\n$repertoire/$nom\n", "g14" ) if ($Flag < 1);
    				$Flag++; $Trouve++;
    				$widget_texte->insert( 'end', $NumLigne .'  -  '. $Ligne, "g12" );
    				$widget_texte->update;
    			}
    			close $IN;
    		}
    		# Répertoires
    		elsif ( -d "$repertoire/$nom" and $recursivite == 1 ) {
    			# récursivité
    			push ( @fichiers, ListerFichiers("$repertoire/$nom", $recursivite) );
    		}
    	}
    	return @fichiers;
    }
     
    ####################################################################################
    sub stop {
      $Stop = 'Lecture stoppée';
      $LabMessage = 'Lecture stoppée';
      $Wm->update;
    	return;
    }
     
    sub fermer {
    	exit (0);
    }
     
    #########################################
    # Configuration des polices de caractères
    #
    sub configurer_tags {
    	my $widget_text = shift;
    	for my $police ( 12 .. 72 ) {
    		if ( $police % 2 == 0 ) {
    			$widget_text->tagConfigure(
    				"g$police",
    				-background => '#ABFAA3',
    				-font      => "{Simplified Arabic} $police {bold}",
    				-justify    => 'left',
    			);
    			$widget_text->tagConfigure(
    				"c$police",
    				-background => '#ABFAA3',
    				-font      => "{Simplified Arabic} $police {bold}",
    				-justify    => 'center',
    			);
    			$widget_text->tagConfigure(
    				"d$police",
    				-background => '#ABFAA3',
    				-font      => "{Simplified Arabic} $police {bold}",
    				-justify    => 'right',
    			);
    		}
    	}
    	return;
    }
     
    #==============================================================
    # Pour avoir les accents sur la console DOS
    # http://perl.developpez.com/faq/perl/?page=Terminal#AccentsDOS
    #==============================================================
    sub ActiverAccentsDOS {
    	my $encodage;
    	# Windows
      	if ( lc($^O ) eq 'mswin32') {
    		eval {
    			my ($codepage) = ( `chcp` =~ m/:\s+(\d+)/ );
    			$encodage = "cp$codepage";
    			foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) {
    				binmode $h, ":encoding($encodage)";
    			}
    		};	
    	}
    	else {
    		$encodage = `locale charmap`;
    		eval {
    			foreach my $h ( \*STDOUT, \*STDERR, \*STDIN, ) {
    				binmode $h, ":encoding($encodage)";
    			}
    		};	
    	}
      return $encodage;
    }
     
    #Sinon :
    #ü 	\x81 	à 	\x85 	è 	\x8A
    #é 	\x82 	ç 	\x87 	ï 	\x8B
    #â 	\x83 	ê 	\x88 	î 	\x8C
    #ä 	\x84 	ë 	\x89 	
     
     
    =pod
    ##############################
    # Retourne encodage du fichier
    #
    # Jedaï :
    			# my $Codage = guess_file_encoding("$IN_Fic");
    			#open my $fh, "<:encoding($name_enc)", $filename
    			#  or die "Can't open $filename : $!\n";
     
    			#unless (open (IN, "<:encoding($Codage)", $IN_Fic)) {
    			#	$LabMessage = "ERREUR : Impossible d'ouvrir $IN_Fic - ENCODAGE=$Codage $! - $@\n";
    			#	$Wm->Label->update();
    			#	return;
    			#}
     
    sub guess_file_encoding {
        my $filename = shift;
        open my $fh, '<:raw', $filename
          or die "Can't open $filename to guess encoding : $!\n";
        die "No data in $filename\n" unless read $fh, my $data, 256;
        my $enc = Encode::Guess->guess($data);
        ref($enc) or die "Couldn't guess encoding of $filename.\n";
        return $enc->name();
    }
    Une fois enlevé tout ce qui concerne l'interface graphique Tk l'essentiel est dans l'extrait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
     
    #============================================================================
    # Nombre d'arguments : 1 ou 2
    # Argument(s)        : un répertoire et valeur 0 ou 1 (récursivité)
    # Retourne           : Tableau de fichier (@fichiers)
    # Origine = http://perl.developpez.com/faq/perl/?page=section1#ListerFichiers
    #============================================================================
    sub ListerFichiers {
    	my ( $repertoire, $recursivite ) = @_;
    	if ( ( not defined $recursivite ) || ( $recursivite != 1 ) ) { $recursivite = 0; }
    	opendir (my $FhRep, $repertoire)
    		or warn "impossible d'ouvrir le répertoire $repertoire\n" and $LabMessage = "Ouverture impossible $repertoire - $! - $@" and return;
    	# Liste fichiers et répertoire sauf (. et ..)
    	my @Contenu = grep { !/^\.\.?$/ } readdir($FhRep);
    	closedir ($FhRep);
     
    	# On récupère tous les fichiers
    	my @fichiers;
    	foreach my $nom ( sort @Contenu ) {
    		last if ($Stop ne "");
    		# Fichiers
    		if ( -f "$repertoire/$nom") {
    			my ($Fic, $Ext) = split (/\./,$nom);
    		#	print "FIC=$Fic == EXT=$Ext  PATTERNFIC=$PatternFic PATTERNEXT=$PatternExt\n";
    			next if ($Fic !~ /$PatternFic/ );
     
    			next if (!$Ext);
     
    			next if ($Ext eq "mp3" );
    			next if ($Ext eq "mp4" );
    			next if ($Ext eq "wav" );
    			next if ($Ext eq "jpg" );
    			next if ($Ext eq "bmp" );
     
    			next if ($Ext !~ /$PatternExt/ );
     
    			push ( @fichiers, "$repertoire/$nom" );
    			$LabRepertoire = "$repertoire/$nom";
    			$IN_Fic  = "$repertoire/$nom";
    			$LabFic  = "$repertoire/$nom";
     
    			my $Encodage = `file "$IN_Fic"`;
    			my $Codage   = '';
    			$Codage      = 'utf8' if ( $Encodage =~ 'UTF-8' );			#	$Codage      = ''     if ( $Encodage =~ 'ISO-8859' );
     
    			unless (open ($IN, "<:".$Codage, $IN_Fic)) {
    				$LabMessage = "ERREUR : Impossible d'ouvrir $IN_Fic - ENCODAGE=$Codage $! - $@\n";
    				$Wm->Label->update();
    				return;
    			}
    			my $NumLigne = 0;
    			my $Flag = 0;
    			while ( my $Ligne = <$IN> ) {
    				$NumLigne++;
    				next if ($Ligne !~ /$PatternRechAvec/ );
    				next if ($PatternRechSans && $Ligne =~ /$PatternRechSans/ );
    				$widget_texte->insert( 'end', "\n\n$repertoire/$nom\n", "g14" ) if ($Flag < 1);
    				$Flag++; $Trouve++;
    				$widget_texte->insert( 'end', $NumLigne .'  -  '. $Ligne, "g12" );
    				$widget_texte->update;
    			}
    			close $IN;
    		}
    		# Répertoires
    		elsif ( -d "$repertoire/$nom" and $recursivite == 1 ) {
    			# récursivité
    			push ( @fichiers, ListerFichiers("$repertoire/$nom", $recursivite) );
    		}
    	}
    	return @fichiers;
    }
    Nb : Fichier Extension Avec & Sans sont des regex
    Ainsi :
    Fichier = .* correspond à n'importe quel nom de fichier
    Extension = .*txt correspond au fichiers d'extension .txt
    Avec est une regex sur un mot ou expression recherché
    Sans est une regex sur un mot ou expression qu'on ne veut pas sélectionner

    En résultat on a :
    - Le nom complet du fichier
    - Le n° de ligne et le mot ou l'expression trouvé

    J'ai fait çà vite fait à partir de bouts de codes déjà existants, c'est à améliorer et surtout à adapter a des besoins spécifiques, codage des fichiers, extensions acceptées/rejetées...
    Ça m'aide bien quand je ne peux pas me fier aux recherches Windows...

    Deux illustres intervenants vont se reconnaître...
    ça donne :

  18. #18
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    La fonction find ne va faire que trouver les fichiers en entrée. Une fois ces fichiers trouvés, il faut encore les ouvrir et les parcourir pour trouver la chaîne recherchée. Ta fonction recherche doit donc ouvrir et parcourir chaque fichier trouvé par find.

    Par ailleurs, je me demande ce que peut bien faire la ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    if(-f $_ =~ /ai/){
    et tout autant ce que tu voudrais que ça fasse. Cela mélange un test sur $_ pour savoir si c'est un fichier et une expression régulière, ce qui n'a pas de sens. "-f $_" vérifie que $_ est un fichier et renvoie une valeur booléen (vrai ou faux). Si c'est un fichier, ça renvoie vrai (1), et 1 ne sera pas reconnu par la regex.

    Enfin, tu demandes à ton utilisateur de saisir quelque chose ($exp) et ne t'en sers pas.

  19. #19
    Futur Membre du Club
    Homme Profil pro
    Analyste d'exploitation
    Inscrit en
    Novembre 2014
    Messages
    18
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Analyste d'exploitation

    Informations forums :
    Inscription : Novembre 2014
    Messages : 18
    Points : 9
    Points
    9
    Par défaut
    Merci pour vos réponses, j'ai pas vraiment envie de repartir sur du neuf mais je compilerai le code un de ces quatre pour jeter un oeil. Merci beaucoup en tout cas.

    Sinon Lolo78

    Oui c'était bien if(-f $_ =~ /$exp/){ qu'il fallait lire et pas /ai/
    En gros je voulais qu'il parcours le fichier (et sous dossier) et stock dans $_ ceux ou il y a l'erreur ($exp)

    Mais bon je m'y suis pris comme une buse visiblement.. j'essai de refaire quelque chose et je reviens vers vous.

    Merci quand même

  20. #20
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 256
    Points
    12 256
    Billets dans le blog
    1
    Par défaut
    Bonsoir,

    voici un exemple presque complet, faisant tout ce dont tu as besoin. J'ai seulement omis les demandes interactives de saisies faites à l'utilisateur (j'avais la flemme et tu sais les faire) et j'ai donc simplement codé en dur le chemin du répertoire ("/home/Laurent") et la chaîne recherchée ("use warnings", je sais que j'en ai beaucoup dans mon répertoire). Pour le reste, le programme ci-dessous explore l'arborescence sous le répertoire racine (c'est File::Find qui le fait) et lit chaque fichier trouvé pour vérifier s'il possède la chaîne recherchée. Dès qu'il trouve la chaîne recherchée, il imprime le nom du fichier concerné avec son chemin dans le fichier de résultat et arrête la lecture du fichier en cours (ça ne sert plus à rien).

    Voici le code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     
    #!/usr/bin/perl
    use strict;
    use warnings;
    use File::Find;
     
    my $path = "/home/Laurent";           # chemin codé en dur
    my $fic_out = "fichiersortie.txt";
    open my $FH_OUT, ">", $fic_out or die "ouverture impossible de $fic_out $!";  # observe la syntaxe recommandée pour ouvrir un fichier en écriture
     
    my $recherche = "use warnings";       # chaine recherchée codée en dur
    find(\&recherche, $path);
     
    sub recherche {
        return unless -f $_;              # on écarte les objets du répertoire qui ne sont pas des fichiers
        my $fic_in = $_;                  # on va traiter le fichier courant
        open my $FH_IN, "<", $fic_in or die "ouverture impossible de $fic_in $!";     # ouverture du fichier courant en lecture, observe la syntaxe
        while (my $ligne = <$FH_IN>) {                          # lecture du fichier courant
            if (index ($ligne, $recherche) >= 0) {              # recherche du motif
                print $FH_OUT $File::Find::name, "\n";          # motif trouvé -> on imprime le fichier avec le chemin
                close $FH_IN; last;                             # inutile de lire la suite du fichier on a trouvé la recherche
            }
        }
        close $FH_IN;                     # la fermeture du handle de fichier n'est pas indispensable, mais je préfère
    }
    Le fichier résultat contient 386 noms de fichiers (presque tous des programmes ou modules Perl), dont 184 dans le répertoire racine choisi pour la recherche et les autres dans ses sous-répertoires. Voici un bref extrait:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    /home/Laurent/a.pl
    /home/Laurent/add2.pl
    /home/Laurent/add_2.pl
    /home/Laurent/analyse_fable.pl
    /home/Laurent/analyse_fable_autre.pl
    /home/Laurent/any.pl
    ...
    /home/Laurent/new_dir/a.pl
    /home/Laurent/Old_PL_programs/2tab.pl
    /home/Laurent/Old_PL_programs/aa.pl
    /home/Laurent/Old_PL_programs/ackermann.pl
    /home/Laurent/Old_PL_programs/ack_nomem.pl
    Tu peux constater que la fonction recherche est assez nettement plus étoffée que ce que tu avais. C'est qu'il y a pas mal de choses à faire dans cette fonction. N'hésite pas à demander si tu veux des éclaircissements.

    J'ai essayé aussi, tout en conservant la structure de ton programme, de respecter les bonnes pratiques communément admises. Observe en particulier comment j'ouvre mes fichiers et vérifie que l'ouverture a réussi. L'ouverture d'un fichier est certainement l'appel système qui échoue le plus souvent (fichier ouvert en lecture inexistant, chemin invalide, etc.), et il ne sert presque toujours à rien de continuer un programme si l'ouverture d'un fichier a échoué.

    Bonne soirée.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Créer 1 fichier xls à enregistrer dans un répertoire "relatif"
    Par olo-rsv-R dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 07/06/2011, 23h44
  2. [MySQL] Analyser gros fichier XML, enregistrement dans une table MySQL
    Par bunsky dans le forum PHP & Base de données
    Réponses: 12
    Dernier message: 20/12/2010, 14h49
  3. [RegEx] Rechercher des éléments et les enregistrés dans un tableau
    Par arnaudperfect dans le forum Langage
    Réponses: 4
    Dernier message: 21/03/2010, 22h41
  4. Réponses: 3
    Dernier message: 13/08/2009, 00h44
  5. Réponses: 8
    Dernier message: 08/08/2008, 11h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo