Quelle est la différence entre `grep`,` egrep` et `fgrep`?

273

Quelqu'un peut -il me dire les différences techniques entre grep, egrep, et fgrepet fournir des exemples appropriés?

Quand dois-je utiliser grepover egrepet vice versa?

mr_eclair
la source
7
superutilisateur a une belle illustration des différences entre grep, egrep, fgrep et pgrep: superuser.com/questions/508881/…
Eric Leschinski

Réponses:

292
  • egrep est 100% équivalent à grep -E
  • fgrep est 100% équivalent à grep -F

Historiquement, ces commutateurs étaient fournis dans des fichiers binaires distincts. Sur certains systèmes Unix très anciens, vous constaterez que vous devez appeler des fichiers binaires distincts, mais sur tous les systèmes modernes, les commutateurs sont privilégiés. La page de manuel de grep contient des informations à ce sujet.

Quant à ce qu’ils font, fait -Ebasculer grep dans un mode spécial afin que l’expression soit évaluée comme une expression ERE (expression régulière étendue), par opposition à sa correspondance de modèle normale. Les détails de cette syntaxe sont sur la page de manuel.

-E, --extended-regexp
Interpréter PATTERN en tant qu'expression régulière étendue

Le -Fcommutateur bascule grep dans un mode différent dans lequel il accepte un motif à mettre en correspondance, puis le divise en une chaîne de recherche par ligne et effectue une recherche OU sur l’une des chaînes sans faire de correspondance de motif spéciale.

-F, --fixed-strings
Interprétez PATTERN comme une liste de chaînes fixes, séparées par des retours à la ligne, chacune d’elles devant être mise en correspondance.

Voici quelques exemples de scénarios:

  • Vous avez un fichier avec une liste de dix noms d'utilisateur Unix en texte brut. Vous souhaitez effectuer une recherche dans le fichier de groupe sur votre ordinateur pour voir si l'un des dix utilisateurs répertoriés appartient à un groupe particulier:

    grep -F -f user_list.txt /etc/group
    

    La raison pour laquelle le -Fcommutateur est utile ici est que les noms d'utilisateur de votre fichier de modèle sont interprétés comme des chaînes de texte brut. Les points, par exemple, seraient interprétés comme des points plutôt que des caractères génériques.

  • Vous voulez rechercher en utilisant une expression de fantaisie. Par exemple, une parenthèse ()peut être utilisée pour indiquer des groupes avec |utilisés en tant qu'opérateur OU. Vous pouvez lancer cette recherche en utilisant -E:

    grep -E '^no(fork|group)' /etc/group
    

    ... pour renvoyer les lignes commençant par "nofork" ou "nogroup". Sans ce -Ecommutateur, vous devriez échapper aux caractères spéciaux impliqués car, avec une correspondance de modèle normale, ils rechercheraient simplement ce modèle exact;

    grep '^no\(fork\|group\)' /etc/group
    
Caleb
la source
17
Certains systèmes n'ont pas egrepou fgrep; -Eet -Fsont standard. Il y a en fait de petites incompatibilités dans egrep: cela traite {légèrement différemment.
Gilles
4
fgreputilise le backend Aho-Corasick, alors qu’il greputilise une version modifiée de Commentz-Walter. Cela signifie que le grepcas le plus défavorable fgrepest la complexité O (mn), tandis que le pire est O (m + n).
Slater Victoroff
2
Gilles "au contraire mon capital", certains systèmes (plus anciens peut-être) peuvent ne pas avoir l'option -F de grep standard mais ont un fgrep, certains ppl se plaignent de cela sur le fil original que j'ai trouvé sur l'utilisation de grep pour les caractères spéciaux
THESorcerer
Je suis récemment tombé sur un système Android sur lequel egrepet grep -Eont été gérés par différents exécutables, BusyBox et BSD grep. Les deux variantes présentaient des différences de comportement pour les constructions de regex non Posix, telles que \s. Cela a conduit à beaucoup de confusion ...
Lii
33

De man grep:

 egrep est identique à grep -E.
 fgrep est identique à grep -F. Invocation directe en tant que egrep ou  
  fgrep est obsolète, mais est fourni pour permettre des applications historiques
  qui comptent sur eux pour fonctionner sans modification.

Vous utilisez fgrepou grep -Fsi vous ne voulez pas que la chaîne masquée soit interprétée comme un motif.

Vous utilisez egrepou grep -Esi vous avez besoin d'utiliser une expression rationnelle.

rozcietrzewiacz
la source
13

egrepet fgrepsont fondamentalement équivalentes à grep -Eet grep -F(respectivement):

   -E, --extended-regexp
          Interpret PATTERN as an extended regular  expression  (ERE,  see
          below).  (-E is specified by POSIX.)

   -F, --fixed-strings
          Interpret  PATTERN  as  a  list  of  fixed strings, separated by
          newlines, any of which is to be matched.  (-F  is  specified  by
          POSIX.)

Les messages d'erreur peuvent toutefois différer.

Stéphane Gimenez
la source
2
ok, mais qu'est - ce qu'une expression régulière étendue? Cela n'explique pas vraiment ci-dessous. Quelques exemples seraient bien ...
isomorphismes
@isomorphismes: Ce lien wikibooks l' explique joliment ...
zb226
8

De "man grep":

Trois programmes variantes, egrep, fgrep et rgrep, sont disponibles. egrep est identique à grep -E. fgrep est identique à grep -F. rgrep est identique à grep -r. L'invocation directe en tant que egrep ou fgrep est obsolète, mais elle est fournie pour permettre aux applications historiques qui en dépendent de s'exécuter sans modification.

Rufo El Magufo
la source
2
La question demande un exemple approprié.
isomorphismes
3

Si vous recherchez une chaîne mot pour mot et que vous voulez être sûr que la chaîne que vous avez passée est interprétée mot pour mot (c.-à-d. Sans risquer de dire qu'un point ou un point d'interrogation sera interprété comme autre chose), utilisez fgrep ou egrep -F.

En ce qui concerne la différence entre egrep et grep, je pense que egrep est la plupart du temps la chose que vous voulez. Le site du manuel GNU répertorie les différences entre grep et egrep qui semblent résider dans la syntaxe: certaines choses nécessitent des barres obliques, d’autres pas. Je pense qu'egrep est plus "compatible" avec les expressions rationnelles perl et javascript, il est donc plus facile pour moi d'utiliser egrep.

Btw. Je vous encourage vivement à essayer ack - il prend en charge les règles PREG et présente des paramètres par défaut plus utiles (par exemple, colorer, sauter des répertoires comme vous ne le faites probablement pas comme .svn, suivre les liens symboliques, et il est un peu plus facile de taper ack que grep -E).

qbolec
la source