简体   繁体   English

使用sed用bash变量替换整行

[英]Replace entire line with bash variable using sed

I want to use sed to replace the entire line at a match with a bash variable. 我想用sed在比赛中用bash变量替换整行。 Replacing with plain text is fine. 用纯文本替换就可以了。

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

If the text I want to replace with is stored in a bash variable, however, this does not work. 但是,如果我要替换的文本存储在bash变量中,则此方法不起作用。

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

How can I achieve this? 我该如何实现?

If you want to do this with sed (which you shouldn't, see below), use 如果您想使用sed进行此操作(不应该这样做,请参见下文),请使用

sed "/fooy/c\\$var"

This is a shell expansion problem. 这是外壳扩展问题。 \\$ in a doubly quoted string means a literal dollar, so $var is not expanded. 用双引号引起来的\\$表示文字美元,因此$var不会扩展。 GNU sed also accepts GNU sed也接受

sed "/fooy/c$var"

as long as you don't specify --posix , but BSD sed (as you may have on FreeBSD or MacOS X) will complain about it. 只要您不指定--posix ,但BSD sed(可能在FreeBSD或MacOS X上就可以)都会对此抱怨。

However, doing this with sed is not a good idea. 但是,使用sed执行此操作不是一个好主意。 Substituting shell variables into sed code is almost never a good idea, because it makes you vulnerable to code injection. 将shell变量替换为sed代码几乎不是一个好主意,因为它使您容易受到代码注入的攻击。 Take, for example, 举个例子

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

That wasn't what we expected, was it? 那不是我们所期望的,是吗? What happens here is that sed , since it is unable do distinguish what you want it to treat as data ( $var ) and code, treats $var as code, and therefore it treats the d after the \\n in it as a command (to delete the current line). 此处发生的是sed ,因为它无法区分想要将其视为数据( $var )和代码,将$var视为代码,因此它将\\n后的d视为命令(删除当前行)。 A better way is to use awk : 更好的方法是使用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

This sidesteps the code injection issue by not treating $var as code. 通过不将$var视为代码来避开代码注入问题。

Don't escape the $ symbol. 不要逃避$符号。 In bash, variables are referred by $variable-name . 在bash中,变量由$variable-name引用。 If you do escaping the $ symbol, then the bash won't consider it as a variable. 如果您确实转义了$符号,则bash不会将其视为变量。 It would treat $var as literal $var . 它将$var当作文字$var

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM