如何在 sed 的命令中使用 shell 变量?

Nid*_*dal 4 shell sed quoting variable

我们知道我们可以使用 $ 符号获取变量的值:

x=3
echo $x
3
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以用来在不使用 $ 符号的情况下获取值。

我问这个是因为 $ 符号是一个特殊字符 to sed,并且sed: -e expression #1, char 31: unterminated s' command在尝试执行此操作时出现错误:

A=25 #lineNumber
destStr="192.168.1.3 192.168.1.4"
sed ""$A"s/Allow from .*/Allow from $destStr/" -i test2
Run Code Online (Sandbox Code Playgroud)

destStr当我使用转义字符时,它会打印字符串(不是值)\

sed ""$A"s/Allow from .*/Allow from \$destStr/" -i test2
Run Code Online (Sandbox Code Playgroud)

使用echo代替sed

25s/Allow from .*/Allow from  192.168.1.3
192.168.1.4
/ -i test2
Run Code Online (Sandbox Code Playgroud)

cel*_*chk 5

正如最终编辑所揭示的,问题与美元符号无关,而是由 的内容引起的deststr,这不是192.168.1.3 192.168.1.4两行,一行只192.168.1.3包含 另一行只包含192.168.1.4,两行都以换行符结尾。即变量替换后的实际命令为:

sed "25s/Allow from .*/Allow from  192.168.1.3
192.168.1.4
/" -i test2
Run Code Online (Sandbox Code Playgroud)

现在sed逐行解释它的命令行,因此它尝试解释的第一个命令是:

25s/Allow from .*/Allow from  192.168.1.3
Run Code Online (Sandbox Code Playgroud)

这显然是一个未终止的s命令,因此由sed它报告。

现在你找到的解决方案,使用echo,工作,因为

echo $var
Run Code Online (Sandbox Code Playgroud)

调用带有两个参数的echo (因为空格没有被引用,它被解释为参数分隔符),第一个是192.168.1.3,第二个是192.168.1.4; 两者都是 shell 不会进一步解释的形式。

现在echo只输出由空格分隔的(非选项)参数,因此您现在可以作为命令行:

sed "25s/Allow from .*/Allow from  192.168.1.3 192.168.1.4/" -i test2
Run Code Online (Sandbox Code Playgroud)

如预期。

但是请注意,对于命令替换,您应该$()尽可能使用反引号代替反引号,因为反引号很容易出错。因此,以下执行您想要的操作:

sed "$A s/Allow from .*/Allow from $(echo $destStr)/" -i test2
Run Code Online (Sandbox Code Playgroud)

请注意,我还利用了sed允许地址和命令之间有空格的事实,以简化引用。在不可能有​​这样的额外空间的情况下,您还可以使用以下语法:

sed "${A}s/Allow from .*/Allow from $(echo $destStr)/" -i test2
Run Code Online (Sandbox Code Playgroud)

另请注意,这依赖于这样一个事实,即destStrshell 或sed替换字符串中出现的if都不会解释in中的非空格字符。