这是一个老问题,但这里的答案都没有详细讨论 s/from/to/ 以外的操作。
sed 语句的一般形式是
*address* *action*
其中 address 可以是正则表达式范围或行号范围(或为空,在这种情况下 action 将应用于每个输入行)。比如
sed '1,4d' file
将删除第 1 到 4 行(address 是行号范围 1,4,action 是 d 删除命令);和
sed '/ick/,$s/foo/bar/' file
将在正则表达式ick 上的第一个匹配项和文件末尾之间的任何行上用bar 替换第一次出现的foo(地址 是范围@987654331 @ 并且 action 是 s 替代命令 s/foo/bar/)。
在这种情况下,如果ick 来自一个变量,你可以这样做
sed "/$variable/,\$s/foo/bar/"
(注意使用双引号而不是单引号,以便shell可以插入变量,并且必须在双引号内引用文字美元符号)但是如果变量包含斜杠,则会出现语法错误. (shell 扩展变量,然后将结果字符串传递给sed;所以sed 只看到文字文本——它没有shell 变量的概念。)
解决方法是使用不同的分隔符(显然,您需要能够使用变量值中不能出现的字符),但与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
在第二个。