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

Shell et commandes POSIX Discussion :

Read et grep


Sujet :

Shell et commandes POSIX

  1. #1
    Futur Membre du Club Avatar de Hakuna_Maths_ata
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 10
    Points : 5
    Points
    5
    Par défaut Read et grep
    Bonsoir,


    mon programme doit lire l'entrée standard jusque sa fin et afficher les lignes contenant le mot hello :

    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
     
    #! /bin/bash
     
     
    echo "Veuillez saisir votre texte: "
     
    read text
     
    case "$text" in 
    *bonjour* ) grep -w "hello" ;;
    *) echo "ne contient pas hello" ;;
    esac
     
     
    exit 0
    si je remplace le grep par un echo, cela fonctionne mais avec le grep, cela ne fonctionne pas... Quelqu'un pourrait-il me donner une indication ?

    Merci d'avance !

  2. #2
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    salut,

    tu te trompes sur le fonctionnement des case/esac et de grep, pour le moins grep quoi dans_quel_fichier(s) ou echo "texte" | grep quoi.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #!/bin/bash
     
    echo "Veuillez saisir votre texte: "
    read text
     
    case "$texte" in
      *hello*|*bonjour*) echo "coucou";;
      *) echo "ne contient pas de salutation";;
    esac
    ici c'est le pattern-matching de case/esac qui remplace grep, et ça va bien que dans ce cas là ça fonctionne, mais de manières plus correcte en général on grep avec les bonnes options, et on teste soit le code de retour de grep soit ce qu'il renvoie sur la sortie standard

    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
    #!/bin/bash
     
    echo -n "Veuillez saisir votre texte: "
    read text
     
    contenu=$(echo "$text" | grep -Eo "bonjour|hello")
    coderet=$?
     
    if [ "$contenu" != "" ]; then
       echo "1: coucou"
    else
       echo "1: ne contient pas de salutation"
    fi
     
    if [ $coderet -eq 0 ]; then
       echo "2: coucou"
    else
       echo "2: ne contient pas de salutation"
    fi
    et l'exécution:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Veuillez saisir votre texte: bonjour tout le monde
    1: coucou
    2: coucou
     
    Veuillez saisir votre texte: hello world !
    1: coucou
    2: coucou
     
    Veuillez saisir votre texte: salut tout le monde
    1: ne contient pas de salutation
    2: ne contient pas de salutation

  3. #3
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    J'ai quelques interrogations à la lecture de ton script :
    • Si tu cherches les lignes contenant hello, pourquoi testes-tu sur *bonjour* ? (ligne 10)
    • grep attend un fichier en entrée. Où est-il mentionné ? (ligne 10)
    • Tu précises que ton programme doit (...) afficher les lignes contenant le mot hello. Où est-ce fait ?
    • Il n'y a pas de boucle, ton script ne lira qu'une ligne avant de sortir. Est-ce bien le comportement attendu ?
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  4. #4
    Futur Membre du Club Avatar de Hakuna_Maths_ata
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Bonjour,


    d'abord, merci d'avoir répondu aussi rapidement.
    Pour la confusion "bonjour"/"hello", c'est parce que j'ai fait plusieurs essais pour le faire marcher... j'ai essayé différentes combinaisons pour trouver miraculeusement une réponse (je n'en suis pas fière) puis l'expliquer.
    J'aimerais que mon programme lisent tout un texte. J'ai essayé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    while [ read $text ]; do ... done
    mais ca ne sortait jamais de la boucle. J'ai donc pensé à ajouter un booléen déclaré avant la boucle tel que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    tr=0
    while [ read $text ] && [ $tr -eq 0 ]; do 
    case
     ... 
    esac
     tr=1
     done
    mais ca ne fonctionnait toujours pas.

    Je pensais que l'on pouvait utiliser grep sans fichier en sortie et que par défaut, cela afficherait le résultat sur la sortie standard. De plus, je pensais que grep permettait de sélectionner des lignes entières du texte passé en entrée (celles qui contiennent un mot en particulier).

  5. #5
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Des pistes :
    read retourne vrai tant qu'il ne rencontre pas une fin de fichier, qui peut être simulée au clavier par Ctrl-D
    La sortie de grep se fait bien sur la sortie standard et l'entrée, sans information complémentaire, sur l'entrée standard.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  6. #6
    Futur Membre du Club Avatar de Hakuna_Maths_ata
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Logiquement, j'aurais quelque chose comme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    #! /bin/bash
     
    echo "Veuillez saisir votre texte: "
     
    while [ read $text ]; do
     
    case "$text" in 
    *hello* ) grep -w "hello" ;; 
    *) echo "pas de hello dans le texte" ;;
    esac
    done
     
    exit 0
    mais dans ce cas, j'ai un affichage infini de "pas de hello dans le texte" et ne me laisse pas la main pour saisir un texte . Idem si j'ajoute un booleen...

  7. #7
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 286
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 286
    Points : 12 742
    Points
    12 742
    Par défaut
    Bonjour,
    Voici ton dernier script corrigé (je te laisse voir les différences par rapport à ta version) :
    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
    #!/bin/bash
    echo "Veuillez saisir votre texte: "
     
    while read text ; do
     
            case "$text" in
            *hello*)
                    echo "hello trouve"
                    break
                    ;;
            *)
                    echo "pas de hello dans le texte"
                    ;;
            esac
    done
     
    exit 0
    PS: pense à indenter ton code, ça aide à relire et surtout ça aide à structurer comment on veut résoudre le problème.
    Cordialement.

  8. #8
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Le paramètre de read doit être un nom de variable.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  9. #9
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    en reprenant le code dans mon premier post il suffit de changer read text par text=$(cat)

  10. #10
    Futur Membre du Club Avatar de Hakuna_Maths_ata
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Merci de vos reponses. Cependant, je rencontre une erreur avec le grep ... Ne devrait-il pas copier la ligne contenant "hello" dans tmp.txt ?

    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
     
    #! /bin/bash
     
    echo "Veuillez saisir votre texte: "
     
    while read text ; do
     
    case "$text" in 
    *hello* ) grep -n "hello" > tmp.txt
    break;;
    *) echo "pas de hello" ;;
    esac
    done
     
    exit 0
    Par contre, quand j'essaie avec echo, ca marche ! Exemple :

    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
     
    #! /bin/bash
     
    echo "Veuillez saisir votre texte: "
     
    while read text ; do
     
    case "$text" in 
    *bonjour* ) echo "hello existe"
    break;;
    *) echo "pas de hello" ;;
    esac
    done
     
     
    exit 0
    Du coup, je me demande si la syntaxe du grep est correcte...Pourriez-vous me donner une indication ?

    Merci d'avance !

  11. #11
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 286
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 286
    Points : 12 742
    Points
    12 742
    Par défaut
    Indente ton code pour clarifier la compréhension de ce que tu veux faire !!!

    Où commence ta boucle ?
    Où termine-t-elle ?
    Que fait le read ?
    Que fait le case et son bloc ?
    Et ensuite, dis nous pourquoi tu veux utiliser le grep dans ce contexte ?

    PS: un grep traite un flux de donnée dont le plus courant est un fichier.
    Ici, comme tu ne lui donnes pas de nom de fichier explicite, il traite l'entrée standard mais le souci, c'est que read aussi...
    Cordialement.

  12. #12
    Futur Membre du Club Avatar de Hakuna_Maths_ata
    Femme Profil pro
    Étudiant
    Inscrit en
    Avril 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 25
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Avril 2017
    Messages : 10
    Points : 5
    Points
    5
    Par défaut
    Voici mon code indenté :

    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
     
    #! /bin/bash
     
    echo "Veuillez saisir votre texte: "
     
    while read text ; do
     
            case "$text" in 
                    *bonjour*)
                                grep -n "*hello*" 
                                break
                                ;;
                    *) 
                                echo "pas de hello"
                                ;;
            esac
    done
     
    exit 0
    Mon read devrait lire un texte jusqu'à la fin de l'entrée standard. Il devrait sélectionner les lignes contenant le mot "hello" sur la sortie standard (en utilisant grep)... J'ai essayé de faire cela avec un fichier en sortie, tel que :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     grep -n  "*hello*" > tmp.txt
    mais ce n'est toujours pas ca...

  13. #13
    Expert éminent Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 035
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 035
    Points : 8 400
    Points
    8 400
    Par défaut
    Citation Envoyé par Hakuna_Maths_ata Voir le message
    Mon read devrait lire un texte jusqu'à la fin de l'entrée standard. Il devrait sélectionner les lignes contenant le mot "hello" sur la sortie standard (en utilisant grep)

  14. #14
    Expert éminent sénior Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 286
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 286
    Points : 12 742
    Points
    12 742
    Par défaut
    Tu désires vérifier qu'il y a le mot "hello" dans la ligne lorsque l'on a eu un "bonjour" sur cette même ligne ?

    C'est ce que l'on comprend quand on lit ton code...

    Sinon, je ne comprend toujours pas le besoin du grep, puisque le case à déjà filtré le mot.
    Cordialement.

  15. #15
    Expert confirmé
    Homme Profil pro
    Développeur informatique en retraite
    Inscrit en
    Avril 2008
    Messages
    2 101
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côtes d'Armor (Bretagne)

    Informations professionnelles :
    Activité : Développeur informatique en retraite

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 101
    Points : 5 849
    Points
    5 849
    Par défaut
    Citation Envoyé par Hakuna_Maths_ata Voir le message
    mon programme doit lire l'entrée standard jusque sa fin et afficher les lignes contenant le mot hello :
    Attention: "lire l'entrée standard jusque sa fin" est différent de "lire une ligne jusqu'à sa fin".

    Pour lire une ligne jusqu'à sa fin, c'est-à-dire jusqu'au caractère de fin de ligne (retour charriot ou return), on peut utiliser la fonction "read".

    S'il s'agit bien de lire l'entrée standard jusqu'à sa fin, c'est différent. Si l'entrée standard est lue interactivement, il faut taper un crtl-D pour signaler la fin de l'entrée, mais si le programme lit le contenu d'un fichier, il s'arrêtera automatiquement lorsqu'il atteindra la fin du fichier.

    Pour moi, la bonne réponse est la dernière de Bufferbob cat | grep hello, que l'on peut simplifier en supprimant l'uuoc en grep hello!

    Le script "mon_script.sh" pourrait donc être:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    #! /bin/bash
     
    echo "Veuillez saisir votre texte (pour terminer, tapez ctrl-D): "
     
    grep "hello"
    De cette manière, tu peux utiliser le script interactivement en tapant ./mon_script.sh, en saisissant interactivement plusieurs lignes et en finissant la saisie par un ctrl-D.

    Mais, si tu as un fichier texte "mon_texte.txt" contenant des lignes, tu peux aussi lui "appliquer" le script en tapant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ./mon_script.sh < mon_texte.txt
    afin d'en extraire les lignes contenant "hello".

Discussions similaires

  1. memoire read
    Par rabi dans le forum OpenGL
    Réponses: 11
    Dernier message: 02/02/2004, 22h59
  2. read committed, serializable... et par défaut k'en est-il?
    Par superdada dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 01/12/2003, 18h58
  3. [LG]problème de read / readln
    Par jeremie60 dans le forum Langage
    Réponses: 7
    Dernier message: 08/06/2003, 23h33
  4. [controle] propriété read only
    Par Fizgig dans le forum Composants VCL
    Réponses: 6
    Dernier message: 28/08/2002, 10h30
  5. CheckBox en Read Only
    Par MrJéjé dans le forum C++Builder
    Réponses: 7
    Dernier message: 23/06/2002, 15h00

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