从文件中读取变量以在 bash 脚本中使用会删除 \

从文件中读取变量以在 bash 脚本中使用会删除 \

所以我加载一个属性文件来定义一些变量。在此示例中,假设它是一个mark!slash\ending\名为 的字符串INPUT

INPUT通过使用以下方式在属性文件中加载来声明:

. ./properties

在哪里

INPUT=mark!slash\ending\

我需要最终输出是通过 SED 形式运行的脚本s!@output@!$INPUT!g,以便在执行时@output@在另一个文件中替换为用户定义的属性文件中的输入(在本例中,变量为INPUT)。我们在 SED 中使用分隔符,因此在添加到 SED 模板文件之前!需要对该字符(以及任何 )进行转义。\

如果我尝试

echo SAFE_INPUT=$(printf '%s\n' 'mark!slash\ending\' | sed 's:[\!]:\\&:g')

我得到了预期的输出

mark\!slash\\ending\\

但是,如果我尝试

SAFE_INPUT=$(printf '%s\n' "${INPUT}" | sed 's:[\!]:\\&:g')

我明白了

mark\!slashending

我假设这与我的字符串与变量的声明有关,但我现在不知道其中的区别以及如何解决问题。

编辑:在进一步测试INPUT时使用

. ./properties

打印为

mark!slashending

所以这不是 SED 的问题,而是读取属性文件的问题。

答案1

问题是当您INPUT在文件中设置变量时properties,如问题所示

INPUT=mark!slash\ending\

并将其作为 shell 脚本获取。

第一个\e被 shell 替换为e\如果后面有一些空格,则该行末尾的 将会被删除,否则表示该行在下一行中继续。所以 的值INPUT已经被修改了。

您要么必须用引号定义您的输入

INPUT='mark!slash\ending\'

就像 Cornholio 的答案一样,否则你必须properties以不同的方式解析你的文件。

使用以下命令,您会将变量 INPUT (以及其他变量,如果 中有更多行的话properties)设置为正确的值。

eval $(sed -e 's:[\!]:\\&:g' properties)

这将使 shell evaluate 命令的输出,sed该命令替换的内容中的\and和。结果将是具有原始名称等的变量。如果您的文件包含一个或多个变量分配,则这将起作用。对于其他 shell 脚本代码,它可能会给出奇怪的结果。!propertiesINPUTproperties

笔记:如果您的输入文件包含其他特殊字符,则处理会更加困难。因此,在没有额外检查的情况下使用eval这种方式可能是脆弱或危险的。

根据您的示例,变量INPUT将具有预期值mark!slash\ending\

之后你可以做

SAFE_INPUT=$(printf '%s\n' "${INPUT}" | sed 's:[\!]:\\&:g')

如果您需要变量SAVE_INPUT来包含mark\!slash\\ending\\.

更好的方法是逐行读取输入,while read -r line并检查和处理该行以分隔变量名称和值。

答案2

如果我使用引用的值执行以下操作INPUT,它会起作用:

> INPUT='mark!slash\ending\'
> SAFE_INPUT=$(printf '%s\n' "${INPUT}" | sed 's:[\!]:\\&:g')
> echo $SAFE_INPUT
mark\!slash\\ending\\

请注意,这是您的脚本的精确副本,INPUT=由我添加。

相关内容