使用 sed 将整行替换为 bash 变量
Replace entire line with bash variable using 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
我怎样才能做到这一点?
不要转义 $
符号。在 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
如果你想用 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
视为代码,因此它将 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
这通过不将 $var
视为代码来回避代码注入问题。
我想使用 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
我怎样才能做到这一点?
不要转义 $
符号。在 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
如果你想用 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
视为代码,因此它将 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
这通过不将 $var
视为代码来回避代码注入问题。