GNU sed --posix и символ новой строки в строке замены

GNU sed --posix и символ новой строки в строке замены

sedВ спецификации POSIXэто утверждениеможно найти (выделено мной):

Последовательность escape '\n' должна соответствовать символу <newline>, встроенному в пространство шаблона.Буквальный <newline> не должен использоваться.в BRE контекстного адреса илив замещающей функции.

Следующая sedкоманда GNU с --posixфлагом противоречит этой спецификации, поскольку в функции замены используется символ новой строки.

$ printf '1X2' | sed --posix 's|X|\n|'
1
2

Так почему же sedвместо сообщения об ошибке была вставлена ​​новая строка?

решение1

"Литеральный <newline> не должен использоваться", В вашем примере не используется литеральный перевод строки. Поэтому эта часть стандарта не имеет значения.

\nявляетсянетбуквальный перевод строки.

решение2

Флаг --posixобеспечивает sedсовместимость с GNU POSIX.

POSIX оставляет поведение s/x/\n/неопределенным:

Значение неэкранированного <обратного слеша>, за которым сразу следует любой символ, отличный от «&», <обратного слеша>, цифры, <новой строки> или символа-разделителя, используемого для этой команды, не определено.

Так что замена xна n, на \n, на новую строку, сообщение об ошибке, перезагрузка компьютера — все это совместимые поведения. Нет никаких причин, по которым GNU sedхотел бы изменить свое поведение там.

Соответствующийприложение(т.е. в данном случае скрипт) не должен \nтам использоваться, именно об этом идет речь в цитируемом вами тексте.

Он отличается в s/[\t]/x/gтом, что POSIX требует заменить \и tна x, и вы увидите, как поведение GNU sedменяется с --posixтам. Для s/[\n]/x/gспецификация POSIX на самом деле неоднозначна. GNU sedменяет свое поведение с , --posixтак что он заменяет \и nна x, но не так ясно, нужно ли это или нет.

решение3

В стандарте указано, что вшаблон поиска(BRE, Basic Regular Expression, на языке POSIX) явный перевод строки не может быть использован, и что там перевод строки представлен как '\n'; и его нельзя использовать взаменаили.

Ваш шаблон поиска не содержит никаких новых строк, явных или представленных как '\n'. У вас есть '\n' в замене. Выше не сказано, как должна быть представлена ​​новая строка (если она вообще должна быть) в тексте замены. GNU sed воспринимает предыдущее как то, что замена на '\n' означает введение новой строки. Разумно.

Связанный контент