В POSIX sed период (точка) соответствует новой строке в многострочном пространстве шаблонов?

В GNU sed это работает. Например, это соответствует двум пустым строкам в многострочном пространстве шаблонов (созданных с помощью N )

 /^\n$/ 

Это стандарт?

Да.

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

Период . , когда используется вне выражения [ bracket ] , является [n] [BE] RE, который должен соответствовать любому символу в поддерживаемом наборе символов, кроме NUL.

У многих реализаций POSIX regexp (таких как grep или sed ) нет проблем с соответствием новой строке, потому что . не будет соответствовать этому, а скорее потому, что их разделитель ввода является новой строкой – и поэтому у них просто нет линий новой строки в проверенной строке.

POSIX grep никогда не может соответствовать новой строке – это синоним w / пустая строка grep . sed аналогичен, за исключением того, что sed может выполнять редактирование или вносить дополнительный ввод в соответствии с командами, написанными по сценарию, и результаты их могут включать в себя новые строки в пространстве шаблонов, даже если они никогда не могут произойти в противном случае. В этом случае, однако,. будет соответствовать \n ewline.

Одна вещь, которая не может быть выполнена с практически любой реализацией POSIX, о которой я знаю, соответствует дополнению новой строки. Это происходит из-за того, что \ обратная косая черта означает себя внутри выражения [ bracket expression ] поэтому \n escape здесь означает только \ и n . Потому что это также, как правило, синтаксическая ошибка для включения литеральной строки в регулярное выражение (хотя одним из исключений является только pax , вы не можете сделать [^ <newline> строку <newline> ] переносимо.

Правильная реализация должна обрабатывать "[$(printf '\1-\11\13-\377')]" , но это ограничивает совпадение в многобайтовых сценариях.

Существует также: "\(\([^[:space:]]*[[:blank:]$(printf '\r\v\f')]*\)*\)" но это немного громоздко.

Тем не менее, что вы можете сделать портативно, это временная замена всех строк новой строки в пространстве шаблонов с каким-то другим символом (и наоборот, конечно) , а затем соответствовать дополнению этого другого символа.

Например:

 printf %s\\n "aa" "bb" "cc" | sed -e 'H;1h;$!d;x;l' -e '# slurps input to last line - usually a bad idea' \ -e 'y/ \n/\n /;l' -e '# transliterates spaces and newlines at once' \ -e 's/[^ ]*//2;l' -e '# substitutes away 2cd sequence of not spaces' \ -e 'y/ \n/\n /;l' -e '# transliterates spaces and newlines again' 

 aa\nb b\nc c$ a\na b\nb c\nc$ a\na c\nc$ aa\n\nc c$ aa cc 

В этом маленьком скрипте есть 4 команды ook – каждый раз, когда пространство шаблонов изменяется после того, как найдена последняя строка. Каждая из команд l ook соответствует одной из первых четырех выходных строк выше, которые легко обозначаются конечным символом $ .

Последние три строки – это результаты всех изменений, напечатанных sed по умолчанию в stdout. Вторая строка полностью пуста, потому что sed заменил вторую последовательность дополнения символа пробела, которая соответствовала всем символам в пространстве шаблонов, за исключением ввода новых строк в то время, и поэтому вторая последовательность была всей второй строкой, новый разделитель строк.

Важно отметить, что это работает, потому что точка (или ее более ограничительная альтернатива [ скобка ] ) соответствует новой строке.