В чем разница между `grep`,` egrep` и `fgrep`?

273

Может кто - нибудь сказать мне технические различия между grep, egrep, и fgrepи обеспечить подходящие примеры?

Когда мне нужно использовать grepснова egrepи наоборот?

mr_eclair
источник
7
superuser имеет отличную иллюстрацию различий между grep, egrep, fgrep и pgrep: superuser.com/questions/508881/…
Эрик Лещинский,

Ответы:

292
  • egrep на 100% эквивалентно grep -E
  • fgrep на 100% эквивалентно grep -F

Исторически эти переключатели были предоставлены в отдельных двоичных файлах. В некоторых действительно старых системах Unix вы обнаружите, что вам нужно вызывать отдельные двоичные файлы, но во всех современных системах предпочтительнее использовать коммутаторы. Страница man для grep содержит подробности об этом.

Что касается того, что они делают, -Eпереключает grep в специальный режим, чтобы выражение оценивалось как ERE (расширенное регулярное выражение), а не как его обычное сопоставление с образцом. Подробности этого синтаксиса находятся на странице руководства.

-E, --extended-regexp
Интерпретировать PATTERN как расширенное регулярное выражение

-FПереключатель переключает Grep в другой режим , в котором он принимает шаблон , чтобы соответствовать, но затем расщепляет этот шаблон вверх в одной поисковой строки в каждой строке и делает поиск или на любой из строк , не делая каких - либо специальных сопоставления с образцом.

-F, --fixed-strings
Интерпретировать PATTERN как список фиксированных строк, разделенных символами новой строки, любой из которых должен соответствовать.

Вот несколько примеров сценариев:

  • У вас есть файл со списком, скажем, десяти имен пользователей Unix в виде простого текста. Вы хотите найти файл группы на своем компьютере, чтобы увидеть, входит ли кто-либо из десяти перечисленных пользователей в какие-либо специальные группы:

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

    Причина, по которой -Fпереключение помогает здесь, состоит в том, что имена пользователей в вашем файле шаблона интерпретируются как строки простого текста. Например, точки будут интерпретироваться как точки, а не как символы подстановки.

  • Вы хотите искать, используя причудливое выражение. Например, круглые скобки ()могут использоваться для обозначения групп с |использованием в качестве оператора ИЛИ. Вы можете запустить этот поиск, используя -E:

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

    ... чтобы вернуть строки, которые начинаются с "nofork" или "nogroup". Без -Eпереключателя вам пришлось бы избегать задействованных специальных символов, потому что при обычном сопоставлении с образцом они просто искали бы этот точный образец;

    grep '^no\(fork\|group\)' /etc/group
    
Калеб
источник
17
Некоторые системы не имеют egrepили fgrep; -Eи -Fявляются стандартными. На самом деле есть небольшая несовместимость egrep: она работает {немного по-другому.
Жиль
4
fgrepиспользует бэкэнд Aho-Corasick, а grepиспользует модифицированную версию Commentz-Walter. Это означает, что grepимеет сложность O (mn) в худшем случае, тогда fgrepкак в худшем случае O (m + n).
Слейтер Викторофф
2
Жиль "au contraire mon capitan", некоторые системы (возможно, более старые) могут не иметь опции -F для стандартного grep, но имеют fgrep, некоторые пользователи жалуются на то, что в исходной ветке, которую я нашел об использовании grep для специальных символов
THESorcerer
Недавно я наткнулся на Android системы , на которой egrepи grep -Eбыли обработаны различными исполняемыми, BusyBox и BSD Grep. Два варианта имели поведенческие различия для не-Posix регулярных выражений, такие как \s. Это привело к большой путанице ...
Лий
33

От man grep:

 egrep такой же, как grep -E.
 fgrep - это то же самое, что и grep -F. Прямой вызов как egrep или  
  fgrep устарела, но предоставляется для разрешения исторических приложений
  что полагаться на них, чтобы работать без изменений.

Вы используете fgrepили, grep -Fесли не хотите, чтобы скопированная строка интерпретировалась как шаблон.

Вы используете egrepили, grep -Eесли вам нужно использовать расширенное регулярное выражение.

rozcietrzewiacz
источник
13

egrepи fgrepв основном эквивалентны grep -Eи grep -F(соответственно):

   -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.)

Сообщения об ошибках могут отличаться.

Стефан Хименес
источник
2
хорошо, но что такое расширенное регулярное выражение? Это на самом деле не объясняет ниже. Несколько примеров были бы хорошими ...
isomorphismes
@isomorphismes: эта ссылка на викибуксы это хорошо объясняет ...
zb226
8

От "man grep":

Доступны три варианта программы egrep, fgrep и rgrep. egrep такой же, как grep -E. fgrep - это то же самое, что и grep -F. rgrep - это то же самое, что и grep -r. Прямой вызов egrep или fgrep устарел, но предоставляется, чтобы позволить историческим приложениям, которые полагаются на них, работать без изменений.

Руфо Эль Магуфо
источник
2
Вопрос требует подходящего примера.
изоморфизм
3

Если вы ищете дословную строку и хотите быть уверены, что переданная вами строка интерпретируется дословно (то есть, не рискуя, что точка или знак вопроса будут интерпретироваться как что-то еще), используйте fgrep или egrep -F.

Что касается разницы между egrep и grep, я думаю, что egrep чаще всего то, что вам нужно. На сайте руководства GNU перечислены различия между grep и egrep, которые, похоже, заключаются в синтаксисе: некоторые вещи требуют косой черты, а другие - нет. Я думаю, что egrep более «совместим» с регулярными выражениями perl и javascript, поэтому мне проще использовать egrep.

Btw. Я настоятельно рекомендую вам попробовать ack - он поддерживает PREG и имеет более полезные значения по умолчанию (например, раскраска, пропуск каталогов «вероятно, не то, что вам нужно», например .svn, возможность переходить по символическим ссылкам, и его немного легче набирать) Ack чем grep -E).

qbolec
источник