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' означает введение новой строки. Разумно.