Почему символы * не подставляются в мою команду sed? - PullRequest
2 голосов
/ 30 апреля 2020

Я не понимаю, почему эта команда:

echo "type    f(type     titi)" | sed 's/type\(\s+\)/void\1**/g'

выводит это:

type    f(type     titi)

Я ожидал бы это:

type    **f(type     **titi)

Я пытался сбежать * в команде sed:

echo "type    f(type     titi)" | sed 's/type\(\s+\)/void\1\*\*/g'

Но вывод остается прежним.

Ответы [ 2 ]

1 голос
/ 03 мая 2020

Команда sed 's/type\(\s+\)/void\1**/g' соответствует type, после этого она сопоставляет и помещает один или несколько пробельных символов в группу, поскольку экранированные круглые скобки захватывают скобки в POSIX BRE.

Все, что вам нужно Для этого нужно использовать * (для сопоставления 0 или более пробелов) вместо + (+ соответствует символу плюса) или - если вам нужно сопоставить хотя бы один пробел - \{1,\}:

echo "type    f(type     titi)" | sed 's/type\(\s*\)/void\1**/g'

echo "type    f(type     titi)" | sed 's/type\(\s\{1,\}\)/void\1**/g'

Оба дают ожидаемый результат.

1 голос
/ 30 апреля 2020

Проблема не в том, что правая часть регулярного выражения неправильно интерпретируется, а в том, что левая часть вообще не совпадает.


Придерживание BRE , мы можем сделать эту работу с:

sed 's/type\([[:space:]]\{1,\}\)/void\1**/g'

Обратите внимание, что \s был изменен на [[:space:]], а + был заменен на стандартный синтаксис \{1,\} , (В GNU-версиях sed можно также использовать \+ в BRE, но это расширение, а не стандартное поведение).


Или мы можем переключиться на ERE путем добавления аргумента -r, и в этом случае нам больше не нужны обратные слеши вокруг наших группирующих паренов, и + гарантированно будет работать.

sed -re 's/type([[:space:]]+)/void\1**/g'
...