Об использовании опции -E в sed(1)

[developer-notes] [sed] [posix] [gnu] [gnu-brain-damage]

В POSIX описано два вида регулярных выражений — Basic (BRE) и Extended (ERE). И например, grep умеет переключаться на ERE при помощи стандартного ключа -E.

Плохая новость — такого стандартного ключа нет у sed.

Вот просто нет и всё. sed -E — нестандартно. А BRE, особенно в интерпретации POSIX, — это такая шляпа, что пользы от такого sed чуть меньше, чем нифига.

Откроем документацию. FreeBSD:

The -E, -I, -a and -i options, the special meaning of -f -, the prefixing
"+" in the second member of an address range, as well as the "I" flag to
the address regular expression and substitution command are non-standard
FreeBSD extensions and may not be available on other operating systems.

То же самое примечание находим в NetBSD.

То же самое примечание находим в Solaris.

И вдруг внезапный GNU sed:

-E, -r, --regexp-extended
     use extended regular expressions in the script (for portability use POSIX -E).

Тут я поперхнулся и полез на сайт Open Group. В издании 2018-го года ключ -E отсутствует.

Открываем info sed.

'-E'
'-r'
'--regexp-extended'
     Use extended regular expressions rather than basic regular
     expressions.  Extended regexps are those that 'egrep' accepts; they
     can be clearer because they usually have fewer backslashes.
     Historically this was a GNU extension, but the '-E' extension has
     since been added to the POSIX standard
     (http://austingroupbugs.net/view.php?id=528), so use '-E' for
     portability.  GNU sed has accepted '-E' as an undocumented option
     for years, and *BSD seds have accepted '-E' for years as well, but
     scripts that use '-E' might not port to other older systems.  *Note
     Extended regular expressions: ERE syntax.

Ага… Так в каком же году -E приняли в стандарт, если в самом свежем (как мне казалось) SUSv4-2018 этого ключа нет? И по указанной ссылке https://www.austingroupbugs.net/view.php?id=528 видим, что “Status: Resolved => Applied” произошло в марте 2020-го. То есть по меркам неспешных динозавров стандартизации, только вчера.

При этом в документацию GNU sed информацию добавили в 2013-м году.

Как это работает? В каком стандарте читать про эту опцию, если её нет в SUSv4? Без понятия.

Хорошая новость в том, что ключ -E действительно понимают большинство выживших систем, которые вы, вероятно, можете встретить в дикой природе. А не понимают, если верить мануалу:

Но лично мои шансы иметь дело с этими двумя ОС строго равны нулю, так что пофиг.

И еще мне стало интересно, когда ключ -E был добавлен в GNU sed. Произошло это в этом коммите:

и не было документировано нигде, даже в тексте коммита. До 2013-го года опция оставалась недокументированной.

То есть сначала они забыли её документировать вообще. А потом резко документировали сразу как POSIX-compliant и без ссылки на нормативный документ.

Мда… качество работы над кодом и документацией в проекте GNU временами не радует.

2021.11.25