This is an old question, but none of the answers here discuss operations other than s/from/to/
in much detail.
The general form of a sed
statement is
*address* *action*
where address can be a regex range or a line number range (or empty, in which case the action is applied to every input line). So for example
sed '1,4d' file
will delete lines 1 through 4 (the address is the line number range 1,4
and the action is the d
delete command); and
sed '/ick/,$s/foo/bar/' file
will replace the first occurrence of foo
with bar
on any line between the first match on the regex ick
and the end of the file (the address is the range /ick/,$
and the action is the s
substitute command s/foo/bar/
).
In this context, if ick
came from a variable, you could do
sed "/$variable/,\$s/foo/bar/"
(notice the use of double quotes instead of single, so that the shell can interpolate the variable, and the necessity to quote the literal dollar sign inside double quotes) but if the variable contains a slash, you will get a syntax error. (The shell expands the variable, then passes the resulting string to sed
; so sed
only sees literal text - it has no concept of the shell's variables.)
The cure is to use a different delimiter (where obviously you need to be able to use a character which cannot occur in the variable's value), but unlike in the s%foo%bar%
case, you also need a backslash before the delimiter if you want to use a different delimiter than the default /
:
sed "\\%$variable%,\$s/foo/bar/" file
(inside single quotes, a single backslash would obviously suffice); or you can separately escape every slash in the value. This particular syntax is Bash only:
sed "/${variable//\//\\/}/,\$s/foo/bar/" file
or if you use a different shell, try
escaped=$(echo "$variable" | sed 's%/%\\/%g')
sed "s/$escaped/,\$s/foo/bar/" file
For clarity, if $variable
contained the string 1/2
then the above commands would be equivalent to
sed '\%1/2%,$s/foo/bar/' file
in the first case, and
sed '/1\/2/,$s/foo/bar/' file
in the second.