我想用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
我怎样才能做到这一点?
答案 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