Quelqu'un peut -il me dire les différences techniques entre grep
, egrep
, et fgrep
et fournir des exemples appropriés?
Quand dois-je utiliser grep
over egrep
et vice versa?
Quelqu'un peut -il me dire les différences techniques entre grep
, egrep
, et fgrep
et fournir des exemples appropriés?
Quand dois-je utiliser grep
over egrep
et vice versa?
Réponses:
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 -E
basculer 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 -F
commutateur 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 -F
commutateur 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 -E
commutateur, 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
egrep
ou fgrep
; -E
et -F
sont standard. Il y a en fait de petites incompatibilités dans egrep
: cela traite {
légèrement différemment.
fgrep
utilise le backend Aho-Corasick, alors qu’il grep
utilise une version modifiée de Commentz-Walter. Cela signifie que le grep
cas le plus défavorable fgrep
est la complexité O (mn), tandis que le pire est O (m + n).
egrep
et grep -E
ont é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 ...
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 fgrep
ou grep -F
si vous ne voulez pas que la chaîne masquée soit interprétée comme un motif.
Vous utilisez egrep
ou grep -E
si vous avez besoin d'utiliser une expression rationnelle.
egrep
et fgrep
sont fondamentalement équivalentes à grep -E
et 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.
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.
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).