为什么 sed 给我一个关于未终止的“s”的错误?

Mik*_*e B 9 sed shell-script text-processing

我在 bash 脚本中有一组 sed 替换,并且收到有关未终止的“s”命令的错误。这是 sed 行的样子:

sed -n -e "s/TMPFOO1/$FOO1/" -e "s/TMPFOO2/$FOO2/" -e "s/TMPFOO3/$FOO3/" -e "s/TMPFOO4/$FOO4/" -e "s/TMPFOO5/$FOO5/" /home/foo/template > /home/foo/template/finishedresult
Run Code Online (Sandbox Code Playgroud)

但出于某种原因,bash 不喜欢这样,我收到了一个关于

sed: -e expression #4, char 69: unterminated `s' command
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?我怎样才能让 SED 输入变量?在我看来他们都被终止了。

Gil*_*il' 8

您不能安全地在 sed 命令中插入变量,因为替换是由 shell 执行的,而不是由 sed 执行的。变量的值变成了 sed 语法。例如,在 中"s/TMPFOO1/$FOO1/",如果$FOO1包含换行符,这将导致您观察到的语法错误。如果$FOO1包含 a /,这将终止s命令并可能导致错误或可能导致其他命令被执行(如果/sed之后的内容恰好是有效的 sed 语法)。

虽然您可以进行第一遍替换FOO1以引用其特殊字符以包含在该 sed 命令中,但使用 awk 要简单得多。awk 有一个变量的概念,以及一个用于设置变量初始值的命令行语法。

awk -v FOO1="$FOO1" -v FOO2="$FOO2" -v FOO3="$FOO3" -v FOO4="$FOO4" -v FOO5="$FOO5" '{
    sub(/TMPFOO1/, FOO1);
    sub(/TMPFOO2/, FOO2);
    sub(/TMPFOO3/, FOO3);
    sub(/TMPFOO4/, FOO4);
    sub(/TMPFOO5/, FOO5);
    print;
}' /home/foo/template > /home/foo/template/finishedresult
Run Code Online (Sandbox Code Playgroud)


Mat*_*teo 6

您的$FOO变量之一很可能包含由sed.

我有另一个版本,sed它会生成其他错误消息,但这里有一个类似问题的例子:

$ VAR=a
$ echo i | sed -e "s/i/"$VAR"/"
a
$ tmp> VAR=/
$ echo i | sed -e "s/i/"$VAR"/"
sed: 1: "s/i///
": bad flag in substitute command: '/'
Run Code Online (Sandbox Code Playgroud)

在这种情况下,$VAR包含一个被解释sed为尾部斜杠的字符。