grep: специальный символ +

Я сделал несколько простых тестов с специальными символами grep '+' и '*'

$ echo 'where wh+'> /tmp/toto $ grep 'wh[e]\*' /tmp/toto $ grep 'wh[e]*' /tmp/toto where wh+ $ grep 'wh[e]+' /tmp/toto $ grep 'wh+' /tmp/toto $ grep 'wh[e]\+' /tmp/toto where $ grep -E 'wh[e]*' /tmp/toto where wh+ $ grep -E 'wh[e]+' /tmp/toto where wh+ 

Из тезисов не расширенный grep '+' (и '?') Не интерпретируется как специальный символ, чтобы использовать его как особый символ, он должен быть экранирован. Когда я читаю, grep использует Basic Regular Expressions (без опции -E), в этом случае специальные символы определяются здесь: http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html#tag_09_03 и '? ' «+» не являются специальными символами для BRE.

Но почему экранирование нестандартного символа «+» в BRE делает его особенным?

Это расширение GNU. Из grep(1) manpage :

В GNU grep нет разницы в доступных функциях между базовыми и расширенными синтаксисами. В других реализациях основные регулярные выражения менее эффективны. Следующее описание относится к расширенным регулярным выражениям; после этого обобщаются различия для основных регулярных выражений.

и далее вниз

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

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

Я не совсем понимаю, какой из приведенных выше примеров кажется нарушением определенного поведения?

Отсутствие изменения + изменяет правила.

На этой ссылке на предоставленную вами спецификацию POSIX вы можете прочитать:

Обычный символ – это BRE, который соответствует самому себе: любой символ в поддерживаемом наборе символов, за исключением специальных символов BRE, перечисленных в специальных символах BRE.

Интерпретация обычного символа, которому предшествует символ ('\'), не определена, за исключением:

  • Символы ')', '(', '{' и '}'
  • Цифры от 1 до 9 включительно (см. BRE, соответствующие нескольким символам)
  • Символ внутри выражения скобки

Итак, в основном, поскольку + является обычным символом BRE, поведение grep 'x\+' не указано, некоторые реализации, такие как GNU grep обрабатывают его так же, как grep 'x\{1,\}' ( grep -E 'x+' ), некоторые из тех же, что и grep 'x+' могут обрабатывать некоторые, такие же, как grep 'x\\+' или что-то еще.

Поэтому, если вы хотите сопоставить строку x\+ portably, вы должны написать grep 'x\\+' (или grep 'x[\]+' , или grep -F 'x\+' или grep -E 'x\\\+' или grep -E 'x[\][+]' ).