Это старый вопрос, но ни один из ответов здесь не рассматривает операции, кроме как s/from/to/
более подробно.
Общая форма sed
заявления:
*address* *action*
где адрес может быть диапазоном регулярных выражений или диапазоном номеров строк (или пустым, и в этом случае действие применяется к каждой строке ввода). Так например
sed '1,4d' file
удалит строки с 1 по 4 ( адрес - это диапазон номеров строк, 1,4
а действие - команда d
удаления); и
sed '/ick/,$s/foo/bar/' file
заменит первое вхождение foo
с bar
любой линией между первым матчем на регулярном выражении ick
и в конце файла ( адрес является диапазоном /ick/,$
и действием является s
командой замены s/foo/bar/
).
В этом контексте, если вы ick
пришли из переменной, вы могли бы сделать
sed "/$variable/,\$s/foo/bar/"
(обратите внимание на использование двойных кавычек вместо одинарных, чтобы оболочка могла интерполировать переменную, и необходимость заключать буквальный знак доллара в двойные кавычки), но если переменная содержит косую черту, вы получите синтаксическую ошибку. (Оболочка расширяет переменную, а затем передает полученную строку в sed
; поэтому sed
видит только буквальный текст - он не имеет понятия о переменных оболочки.)
Лекарство - использовать другой разделитель (где, очевидно, вам нужно иметь возможность использовать символ, который не может встречаться в значении переменной), но в отличие от этого s%foo%bar%
случая вам также понадобится обратная косая черта перед разделителем, если вы хотите использовать другой разделитель, чем по умолчанию /
:
sed "\\%$variable%,\$s/foo/bar/" file
(внутри одинарных кавычек, очевидно, достаточно одной обратной косой черты); или вы можете отдельно убрать каждую косую черту в значении. Этот конкретный синтаксис предназначен только для Bash:
sed "/${variable//\//\\/}/,\$s/foo/bar/" file
или если вы используете другую оболочку, попробуйте
escaped=$(echo "$variable" | sed 's%/%\\/%g')
sed "s/$escaped/,\$s/foo/bar/" file
Для ясности, если бы она $variable
содержала строку, 1/2
то приведенные выше команды были бы эквивалентны
sed '\%1/2%,$s/foo/bar/' file
в первом случае и
sed '/1\/2/,$s/foo/bar/' file
во-вторых.