通过sed用多行变量替换字符串中的关键字

Substituting keyword in string with multi-line variable via sed

注:以下问题与有关,但问题的侧重点和输入变量的格式不同(即多行文件的内容).因此,正确的解决方案也可能不同。

似乎只要所述变量包含明确的换行符 (\n),通过 sed 将字符串中的关键字替换为多行变量就有效。

$ target="foo \n bar \n baz"
$ echo "qux\nquux" > file
$ solution=$(cat file)
$ echo "$solution"
qux\nquux
$ echo $target | sed -e "s|bar|$solution|"
foo \n qux
quux \n baz

但是,当我在文本编辑器中打开文件 file 并将换行符替换为换行符时,使用 sed 的替换失败。

# Newline character was manually replaced with linebreak in texteditor.
$ solution=$(cat file)
$ echo "$solution"
qux
quux
$ echo $target | sed -e "s|bar|$solution|"
sed: -e expression #1, char 9: unterminated `s' command

当输入变量没有显式换行符时,我如何更改 sed-命令以执行查找的替换?

Introduction/Setup

sed 不一定是适合这项特定工作的工具。考虑以下选项——每个选项的样本都需要以下设置:

# Run this before testing any of the code below
source='bar'
target='This string contains a target: <bar>'
solution='This has
multiple lines
and /slashes/ in the text'

...并且每个都将发出以下输出:

This string contains a target: <This has
multiple lines
and /slashes/ in the text>

请注意,对于 sed,您需要选择一个不用于表达式的分隔符(因此,对于 s/foo/bar/foobar 可以包含 /);下面的答案都避免了这个限制。


Shell-内置参数扩展

shell可以只用built-in string manipulation functionality进行相关替换:

result=${target//$source/$solution}
echo "$result"

Perl 单行代码作为 sed 替代方案

对于 shell 的内置匹配不合适的较长输入字符串,您还可以考虑使用 perl 单行代码,如 BashFAQ #21:

中所述
in="$source" out="$solution" perl -pe 's/\Q$ENV{"in"}/$ENV{"out"}/g' <<<"$target"