В чем разница между "grep-e" и "grep-E" [закрыто]

у меня есть файл test.txt, в котором есть некоторые отформатированные номера телефонов. Я пытаюсь использовать grep, чтобы найти строки, содержащие номер телефона.

кажется,grep -e "[0-9]{3}-[0-9]{3}-[0-9]{4}" test.txt не работает и не дает никаких результатов. Но!--3-->строительство. Поэтому мне интересно, в чем разница между этими 2 вариантами.

по данным man grep:

- E, --extended-regexp Интерпретировать шаблон как расширенное регулярное выражение (т. е. силу grep вести себя как egrep).

-e pattern, --regexp=pattern Укажите шаблон, используемый при поиске входных данных: вход строка выбирается, если она соответствует любому из указанных шаблонов. Этот параметр наиболее полезен при использовании нескольких параметров-e для укажите несколько шаблонов или когда шаблон начинается с тире ( ' - ').

но я не совсем понимаю. Что такое регулярное выражение?

3 ответов


как вы сказали, grep -E для расширенных регулярных выражений , тогда как -e для основных регулярных выражений. С мужской страницы:

EDIT: как указал Джонатан ниже,grep -e " указывает, что следующий аргумент является (одним из) регулярных выражений, которые должны быть сопоставлены."

основные vs расширенные регулярные выражения

в основных регулярных выражениях метасимволы ?, +, {, |, ( и ) потерять их особый смысл; вместо этого используйте обратные косые версии \?, \+, \{, \|, \( и \).

традиционный egrep не поддержал { мета-характер, и некоторые egrep поддержка реализаций \{ вместо этого, поэтому портативные скрипты должны избегать { in grep -E шаблоны и должны использовать [{] чтобы соответствовать литерал {.

GNU grep -E пытается поддержать традиционное использование, предполагая, что { is не является особенным, если это будет началом недопустимой спецификации интервала. Например, команда grep -E '{1' поиск двух символов строка {1 вместо сообщения о синтаксической ошибке в регулярном выражении. В POSIX.2 позволяет это поведение как расширение, но переносимые скрипты должны избегать его.

, но man-страницы довольно лаконично, поэтому для получения дополнительной информации ознакомьтесь с этой ссылкой:

http://www.regular-expressions.info/posix.html

часть manpage относительно { мета-персонаж, хотя конкретно говорит о том, что вы видите в отношении разницы.

grep -e "[0-9]{3}-[0-9]{3}-[0-9]{4}" 

не будет работать, потому что он не обрабатывает { персонаж, как вы ожидаете. Тогда как

grep -E "[0-9]{3}-[0-9]{3}-[0-9]{4}" 

делает, потому что это расширенная версия grep - или egrep версия для примера.


вот простой тест:

$ cat file
apple is a fruit
so is orange
but onion is not

$ grep -e 'but' -e 'fruit' file #Allows you to pass multiple patterns explicitly
apple is a fruit
but onion is not

$ grep -E 'is (a|not)' file #Allows you to use extended regular expressions like ?, +, | etc
apple is a fruit
but onion is not

на до grep просто говорит, что следующий аргумент-это регулярное выражение. Таким образом:

grep -e 'some.*thing' -r -l .

ищет some следовал по thing на строке во всех файлах текущего каталога и всех его подкаталогах. То же самое может быть достигнуто с помощью:

grep -r -l 'some.*thing' .

(в Linux ситуация запутана поведением GNU getopt() который, если вы не установите POSIXLY_CORRECT в среде, переставляет параметры, поэтому вы также можно запустить:

grep 'some.*thing' -r -l .

и получить тот же результат. В POSIX и других системах, не использующих GNU getopt(), опции должны предшествовать аргументам, а то grep будет искать файл с названием -r и еще называют -l.)

на -E опция изменяет регулярные выражения с 'basic' до 'extended'. Его можно использовать с -e:

grep    -e "[0-9]{3}-[0-9]{3}-[0-9]{4}" test.txt
grep -E -e "[0-9]{3}-[0-9]{3}-[0-9]{4}" test.txt

параметр ERE означает те же регулярные выражения, более или менее используемые быть признанным egrep команда, которая больше не является частью POSIX (заменена на grep -E и fgrep by grep -F).