Я предполагаю, что вы говорите о синтаксисе backrefence, которые являются круглыми скобками ( )
, а не скобками [ ]
По умолчанию sed
будет интерпретировать ( )
буквально и не будет пытаться сделатьВозврат от них.Вам нужно экранировать их, чтобы сделать их особенными, как в \( \)
. Только когда вы используете опцию GNU sed -r
, экранирование будет отменено.С sed -r
, не экранированный ( )
будет создавать обратные ссылки, а экранированный \( \)
будет считаться буквальным.Примеры для подражания:
POSIX sed
$ echo "foo(###)bar" | sed 's/foo(.*)bar/@@@@/'
@@@@
$ echo "foo(###)bar" | sed 's/foo(.*)bar/\1/'
sed: -e expression #1, char 16: invalid reference \1 on `s' command's RHS
-bash: echo: write error: Broken pipe
$ echo "foo(###)bar" | sed 's/foo\(.*\)bar/\1/'
(###)
GNU sed -r
$ echo "foo(###)bar" | sed -r 's/foo(.*)bar/@@@@/'
@@@@
$ echo "foo(###)bar" | sed -r 's/foo(.*)bar/\1/'
(###)
$ echo "foo(###)bar" | sed -r 's/foo\(.*\)bar/\1/'
sed: -e expression #1, char 18: invalid reference \1 on `s' command's RHS
-bash: echo: write error: Broken pipe
Обновление
Из комментариев:
Скобки без захвата только для групп ( )
, поэтому вы можете использовать что-то вроде интервалов {n,m}
без создания обратной ссылки \1
не существует.Во-первых, интервалы не являются частью POSIX sed, вы должны использовать расширение GNU -r
, чтобы включить их.Как только вы включите -r
, любые круглые скобки для групп будут также перехватываться для использования в качестве обратной ссылки.Примеры:
$ echo "123.456.789" | sed -r 's/([0-9]{3}\.){2}/###/'
###789
$ echo "123.456.789" | sed -r 's/([0-9]{3}\.){2}/###\1/'
###456.789