使用sed用bash变量替换整行

时间:2015-01-30 08:56:48

标签: bash sed

我想用sed替换与bash变量匹配的整行。用纯文本替换就可以了。

$ echo -e "foo bar\nfooy bary\nfoot bart" | sed '/fooy/c\text'
foo bar
text
foot bart

但是,如果要替换的文本存储在bash变量中,则不起作用。

$ var="This is poetry."
$ echo -e "foo bar\nfooy bary\nfoot bart" | sed "/fooy/c\$var"
foo bar
$var
foot bart

我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:3)

如果你想用sed(你不应该这样做,见下文),请使用

sed "/fooy/c\\$var"

这是一个shell扩展问题。双引号字符串中的\$表示字面值,因此$var不会展开。 GNU sed也接受

sed "/fooy/c$var"

只要你没有指定--posix,但是BSD sed(就像你在FreeBSD或MacOS X上一样)会抱怨它。

然而,用sed做这个并不是一个好主意。将shell变量替换为sed代码几乎不是一个好主意,因为它使您容易受到代码注入的攻击。举个例子,

$ var=$(echo -e 'something\nd')
$ echo -e "foo bar\nfooy bary\nfoot bart" | sed --posix "/fooy/c\\$var"
something

这不是我们的预期,是吗?这里发生的是sed,因为它无法区分您希望将其视为数据($var)和代码,将$var视为代码,因此它会对{ {1}}之后d作为命令(删除当前行)。更好的方法是使用\n

awk

通过不将$ var=$(echo -e 'something\nd') $ echo -e "foo bar\nfooy bary\nfoot bart" | awk -v var="$var" '/fooy/ { print var; next } 1' foo bar something d foot bart 视为代码来回避代码注入问题。

答案 1 :(得分:1)

不要逃避$符号。在bash中,变量由$variable-name引用。如果您确实转义了$符号,那么bash不会将其视为变量。它会将$var视为文字$var

$ echo -e "foo bar\nfooy bary\nfoot bart" | sed "/fooy/c$var"
foo bar
This is poetry.
foot bart