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 :

resultat d'un grep


Sujet :

Langage Perl

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 624
    Par défaut resultat d'un grep
    Bonjour,

    je débute en Perl, et j'ai un problème pour utiliser la fonction grep inclue dans Perl.

    J'ai le code suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $res=grep($nom_fonc,"nom_de_fonctions.txt");
    Je cherche à vérifier si la chaine de caractère $nom_fonc (un nom de fonction) se trouve dans le fichier nom_de_fonctions.txt (devinez ).

    Selon la doc que j'ai trouvé le grep me renvoie le nombre d'occurences trouvées. Sauf que là $res me renvoie systématiquement 1, même pour des fonctions dont je sais qu'elles ne sont pas dans nom_de_fonctions.txt

    Quelle est mon erreur ?

    Merci pour 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 : 59
    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
    Par défaut
    La fonction grep n'a pas un prototype équivalent à celui d'Unix.

    Elle prends en premier paramètre, une expression (ou un bloc de code retournant une valeur booléenne), et une liste de scalaires (et non un nom de fichier).

    Dans ton cas, il faut donc ouvrir le fichier, et appliquer le grep à la lecture ligne à ligne :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    open my $NOM_FONCTION, "<", "nom_de_fonctions.txt" or die "Impossible d'ouvrir 'nom_de_fonctions.txt' : $!\n";
     
    if (grep /$nom_fonc/, <$NOM_FONCTION>) {
      print "$nom_fonc trouvé dans le fichier\n";
    }
    Ce code est simpliste. En fait, grep retourne soit un booléen (dans un contexte scalaire), soit une liste des éléments du 2e paramètre de grep qui satisfont au critère du premier paramètre.
    Exemple
    :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    open my $NOM_FONCTION, "<", "nom_de_fonctions.txt" or die "Impossible d'ouvrir 'nom_de_fonctions.txt' : $!\n";
     
    my @perl_subs = grep /^\s*sub\s*\w*/, <$NOM_FONCTION>;
    print "Lignes contenant des fonctions perl :\n", join @perl_subs;

  3. #3
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 624
    Par défaut
    Merci.
    Je me sers de la première version, car trouver une fonction présente dans mon fichier nom_de_fonctions active un traitement.

    Pour ouvrir mon fichier j'utilise

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    open(NOM_FONCTION,"nom_de_fonction.txt");
    En dehors de la non-utilisation de "die" pour les cas d'erreur, y a t'il une différence notables entre les deux écritures ?

  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 : 59
    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
    Par défaut
    L'usage des variables scalaires comme File handle à la place des typeglob (qui sont des barewords, c'est à dire des identifiants sans sigil, comme des mots-clés) est à mon avis à privilégier.
    Cela permet de limiter l'étendue de ces variables au lieu de les définir de manière globale. Cependant, leur usage est un peu plus contraignant :
    - dans certains cas, pour éviter toute ambiguité, il faut les encadrer dans des accolades lors des print (du coup, la consigne est de toujours les encadrer) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print { $FILE } "Hello world !";
    - il faut que le scalaire soit "indéfini" (soit undef) avant de faire l'open. Si l'on souhaite ré-utiliser un scalaire comme nouveau file handle, il faut d'abord l'indéfini :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    open my $FILE, "<", "toto.txt";
    # ...
    undef $FILE;
    open $FILE, "<", "tata.txt";
    # ...
    Quant à l'usage de open à trois argument au lieu de open à deux arguments, sont usage est plus souple et me semble à priori préférable (on dé-corrèle le type d'ouverture du nom du fichier).

  5. #5
    Membre expérimenté Avatar de ManusDei
    Homme Profil pro
    vilain troll de l'UE
    Inscrit en
    Février 2010
    Messages
    1 624
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : vilain troll de l'UE

    Informations forums :
    Inscription : Février 2010
    Messages : 1 624
    Par défaut
    Donc, cette écriture est correcte et respecte les "bonnes pratiques" ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    open(ECRIRE,">resultat.txt");
     
    foreach $file (@files) {
       open(FILEH,$file);
       print ECRIRE { $file } "\n";
       while(<FILEH>) {
          # du traitement
       }
       close(FILEH); # optionnel ou non, vu que suivi par undef ?
       undef(FILEH);
    }

  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 : 59
    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
    Par défaut
    Non, pas tout à fait.

    Les premières bonnes pratique à adopter, sont l'ajout de "use strict" et "use warnings", qui permet de faire les premières corrections.

    Voici au final comment j'écrirais ton programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    open my $ECRIRE,">", "resultat.txt" or die "Can't open resultat.txt for writting: $!";
     
    foreach my $file (@files) {
       open my $FILEH, "<", $file;
       print { $ECRIRE } $file,"\n";
       while(<$FILEH>) {
          # du traitement
       }
       close $FILEH; # optionnel, vu que suivi par undef
       undef $FILEH;
    }
    Mais n'oublie pas qu'en perl, TIMTOWTDI.
    En particulier, l'usage des parenthèses est sujet à débat. Personnellement, je réserve l'usage des parenthèses aux fonctions que j'ai créées, et j'évite autant que faire se peut leur usage pour les functions perl. En règle générale, je les utilise toujours pour les méthodes de classe. Il faut savoir que les parenthèses sont souvent inutiles, sauf parfois, pour éviter les ambiguïtés (comme par exemple lorsque tu définis une liste dont un élément est le retour d'une fonction possédant des paramètres).

  7. #7
    Membre éclairé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Septembre 2006
    Messages
    519
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Septembre 2006
    Messages : 519
    Par défaut
    Citation Envoyé par Philou67430 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    open my $NOM_FONCTION, "<", "nom_de_fonctions.txt" or die "Impossible d'ouvrir 'nom_de_fonctions.txt' : $!\n";
     
    if (grep /$nom_fonc/, <$NOM_FONCTION>) {
      print "$nom_fonc trouvé dans le fichier\n";
    }
    Ce code est simpliste. En fait, grep retourne soit un booléen (dans un contexte scalaire), soit une liste des éléments du 2e paramètre de grep qui satisfont au critère du premier paramètre.
    Si $nom_fonc n’est pas une regexp, il me semble préférable de l’y protéger :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (grep /\Q$nom_fonc/, <$NOM_FONCTION>) {
        # ...
    }
    Par ailleurs, la valeur de retour de grep en contexte scalaire n’est pas spéciale, c’est la valeur de toute liste évaluée en contexte scalaire : son nombre d’éléments. Ainsi, en contexte scalaire, grep renvoie le nombre d’éléments ayant satisfait le prédicat (qui peut effectivement être utilisé comme un booléen pour voir si au moins un élément l’a satisfait).

  8. #8
    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 : 59
    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
    Par défaut
    Citation Envoyé par spidermario Voir le message
    Si $nom_fonc n’est pas une regexp, il me semble préférable de l’y protéger :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if (grep /\Q$nom_fonc/, <$NOM_FONCTION>) {
        # ...
    }
    Tout à fait d'accord : je découvre du coup \Q ... \E, qui évite l'usage de quotemeta en dehors de la fonction (qui nécessite l'usage d'une 2e variable locale si l'on ne souhaite pas d'effet de bord sur $nom_fonc).
    Par contre, ne faut-il pas ajouter le \E (ou bien ce dernier devient facultatif s'il est à la fin de la regexp) ?

    Par ailleurs, la valeur de retour de grep en contexte scalaire n’est pas spéciale, c’est la valeur de toute liste évaluée en contexte scalaire : son nombre d’éléments.
    Tout à fait juste. Mon explication était tout aussi simpliste que le code

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

Discussions similaires

  1. affichage resultat de la commande grep
    Par koukou11 dans le forum Unix
    Réponses: 3
    Dernier message: 20/04/2011, 13h27
  2. resultat grep non attendu
    Par nina2007 dans le forum Shell et commandes GNU
    Réponses: 5
    Dernier message: 19/07/2010, 12h13
  3. Proposer le resultat d'une requête en téléchargement
    Par Lux interior dans le forum XMLRAD
    Réponses: 5
    Dernier message: 17/02/2003, 15h44
  4. [VB6] [Excel] Résultat d'une requete ds une feuille
    Par elifqaoui dans le forum VB 6 et antérieur
    Réponses: 12
    Dernier message: 07/01/2003, 17h52
  5. Resultat requete SQL
    Par PierDIDI dans le forum Bases de données
    Réponses: 2
    Dernier message: 23/07/2002, 13h43

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