Использование разных разделителей в командах sed и диапазонах адресов

Я использую sed в сценарии оболочки для редактирования имен файловых систем. Предположим, я хочу заменить:

  • /foo/bar

С:

  • /baz/qux

Однако команда sed s/// использует косую черту / в качестве ограничителя. Если я это сделаю, я вижу сообщение об ошибке, например:

▶ sed 's//foo/bar//baz/qux//' FILE
sed: 1: "s//foo/bar//baz/qux//": bad flag in substitute command: 'b'

Точно так же иногда я хочу выбрать линейные диапазоны, такие как линии между шаблоном foo/bar и baz/qux. Опять же, я не могу сделать это:

▶ sed '/foo/bar/,/baz/qux/d' FILE
sed: 1: "/foo/bar/,/baz/qux/d": undefined label 'ar/,/baz/qux/d'

Что я могу сделать?

Ответ 1

Вы можете использовать альтернативный разделитель регулярных выражений в качестве шаблона поиска, обратив его:

sed '\,some/path,d'

И просто используйте его как есть для команды s:

sed 's,some/path,other/path,'

Однако вы, вероятно, хотите защитить другие метасимволы; это хорошее место для использования Perl и quotemeta, или эквивалентов на других языках сценариев.

От man sed:

/regexp/
Строки соответствия, соответствующие регулярному выражению regexp.

\cregexpc
Строки соответствия, соответствующие регулярному выражению regexp. c может быть любым символом, отличным от обратного слэша или новой строки.

s/regular expression/replacement/flags
Подставьте заменяющую строку для первого экземпляра регулярного выражения в пространстве шаблонов. Любой символ, отличный от обратной косой черты или новой строки, может использоваться вместо косой черты, чтобы разграничить RE и замену. В RE и замене сам разделитель RE может использоваться как буквенный символ, если ему предшествует обратная косая черта.