Probleme expressions commande man man | grep -e “reg_expr"*

Résolu/Fermé
45K Messages postés 13 Date d'inscription dimanche 20 décembre 2020 Statut Membre Dernière intervention 8 juin 2023 - Modifié le 27 janv. 2023 à 17:06
mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 - 27 janv. 2023 à 17:36

Bonjour,

J'aimerais corriger les erreurs que j'ai commises sur le terminal s'il vous plait.

1. Afficher les lignes se terminant par un point.

man man | grep -e ".$"

2. Afficher les lignes contenant des nombres à quatre chiffres

man man | grep -e "[0-9]\{4\}$ "*

3. Afficher les lignes contenant des mots contenant la lettre s coincer entre deux voyelles

man man | grep -e "[a e i o u y] *s*"*

Je pense qu'il y a un problème au niveau de la première parce qu'elle me sélectionne toute la phrase dans le manuel man du coup, je ne sais pas si c'est bon.

Puis, la deuxième elle ne m'affiche rien, je suis sûr qu'il y a une erreur

Enfin, la troisième, elle m'affiche toutes les voyelles alors que je veux les "s."

Je vous remercie d'avance.

Linux / Firefox 86.0

A voir également:

1 réponse

mamiemando Messages postés 33079 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 23 avril 2024 7 749
Modifié le 27 janv. 2023 à 17:43

Bonjour,

Pour apprendre à utiliser grep, je t'invite à utiliser l'option --color. En rouge, tu verras apparaître ce qui a été "grepé".

  1. Le méta-caractère "." signifie n'importe quel caractère. Ce n'est pas ce que demande la question, on veut filtrer sur le caractère "." qui s'écrit en expression rationnelle "\." ou "[.]". L'option -e est ici inutile car tu n'utilise pas d'opérateur avancé.
    man man | grep --color "[.]$"
  2. Je pense que tu n'as pas compris ce que tu as écrit.
    • Le caractère "$" ancre le motif en fin de ligne. Par exemple si tu fais un grep en utilisant l'expression rationnelle "xyz$", tu cherches les lignes qui finissent par xyz. En l'occurrence, je pense que tu cherches les lignes contenant quatre chiffres consécutifs, où qu'il soient dans la ligne. Le caractère $ est donc en trop.
    • Le caractère "*" a un sens différent selon où tu le mets.
      • À l'extérieur des guillements, le shell substitue * par la liste des fichiers dans le dossier courant.
      • Dans les guillements, c'est l'étoile de Kleene, qui indique qu'il faut chercher un motif répété n fois, avec n >= 0. Cela reviendrait donc à chercher une séquence de 0 entiers, 4 entiers, 8 entiers, etc.
      • Dans tous les cas, on voit que * n'a aucune utilité pour cette question
    • On a besoin de l'option "-e" avec grep ou il faut utiliser egrep car tu utilises l'opérateur {}. C'est adapté dans le cas présent : 
      man man | grep --color -e "[0-9]\{4\}"
      man man | egrep --color "[0-9]{4}"
    • On aurait pu aussi écrire ceci (bien que ce soit moins élégant) :
      man man | grep --color "[0-9][0-9][0-9][0-9]"
  3. Je pense que tu devrais relire ton cours sur les expressions rationnelles.
    • Pour rappel, une expression rationnelle est une manière de modéliser un automate non déterministe (NFA) qui capture un langage régulier en le représentant par une chaîne de caractère, comme l'explique cette page.
      • Quand tu écris une expression rationnelle, ce serait donc une bonne idée que tu dessines le NFA correspondant et que tu te demandes s'il a une chance de capturer les chaînes qui t'intéressent.
      • Tu peux ensuite déterminiser cet automate pour en améliorer la lisibilité (DFA).
      • Voici ce que ça donne avec ta solution :
        nfa & dfa
        • On part de l'état initial (0). On doit arriver à un état final (double cercle) pour capturer une chaîne.
        • Les transitions étiquetés par epsilon peuvent être traversées sans consommer de caractère.
        • Les transitions sans étiquette sont en réalité étiquetés par le caractère espace (qui ne se voit pas).
        • Les autres transitions consommer le caractère qui les étiquette.
        • Étant donné un mot, on part de l'état 0 et on regarde où le premier caractère pour déterminer le prochain état courant.
          • Dans le cas d'un DFA, cela correspond à 0 ou 1 état cible. Par exemple dans le DFA on voit que si le premier caractère est une voyelle, on peut atteindre l'état 1 et continuer à jouer. Sinon perdu, il n'y a pas d'état cible et donc la chaîne qu'on traite n'est pas capturée.
          • Dans le cas du NFA, il peut y avoir 0, 1 ou plusieurs états cibles.
        • On répète la procédure en avançant, caractère par caractère, jusqu'à atteindre la fin du mot. Si l'état courant est un état final (double cercle), le mot est capturé par l'automate, et donc par n'importe quelle expression rationnelle qui lui correspond.
    • Dans la solution que tu proposes, tu as écrit :
      • "[a e i o u y]": cherche un caractère parmi {'a', 'e', 'i', 'o', 'u', 'y', ' '} : ce serait donc plutôt "[aeiouy]".
      • " *": puis cherche le caractère " " répété 0 ou plus
      • "s*": puis cherche le caractère "s" répété 0 ou plus
      • Je te laisse à la lumière de ces explications données réfléchir à la troisième réponse.

Bonne chance

2