sed:-e表达式#1,字符101:未终止的“s”命令

sed:-e表达式#1,字符101:未终止的“s”命令

有人可以告诉我这里出了什么问题吗-

sed -i "s|##CONNECTION_DETAILS##|${CONNECTION_DETAILS}|g" dep.yaml. 

CONNECTION_DETAILS 的值采用编码形式:

CSAgewogICAgICAgICJjb25uZWN0aW9uX25hbWVfMSI6ICJPRlNBQV9BTkFMWVRJQ1NfUFVCIiwKICAgICAgICAiZGF0YWJhc2VfbmFtZV8xIjogIk9GU0FBX0FOQUxZVElDU19QVUIiLAogICAgICAgICJiaV9TZXJ2aWNlc18xIjpbImR2IiwicnBkIiwiYmlwdWJsaXNoZXIiXQogICAgICB9Cg==

为了:

{
    "connection_name_1": "OFSAA_ANALYTICS_PUB",
    "database_name_1": "OFSAA_ANALYTICS_PUB",
    "bi_Services_1":["dv","rpd","bipublisher"]
}

答案1

您的CONNECTION_DETAILS变量包含 LF ( \n) 字符。

所以,sed不要理解未终止的s命令。第二个之前的 LF "

和:

> CONNECTION_DETAILS='CSAgewogICAgICAgICJjb25uZWN0aW9uX2
5hbWVfMSI6ICJPRlNBQV9BTkFMWVRJQ1NfUFVCIiwKICAgICAgICAi
ZGF0YWJhc2VfbmFtZV8xIjogIk9GU0FBX0FOQUxZVElDU19QVUIiLA
ogICAgICAgICJiaV9TZXJ2aWNlc18xIjpbImR2IiwicnBkIiwiYmlw
dWJsaXNoZXIiXQogICAgICB9Cg=='

两种解决方案:

  1. 删除 LF 字符
> lf=$'\n'
> echo "xxxxx ##CONNECTION_DETAILS## xxxxx" | sed -e "s|##CONNECTION_DETAILS##|${CONNECTION_DETAILS//$lf}|g"
xxxxx CSAgewogICAgICAgICJjb25uZWN0aW9uX25hbWVfMSI6ICJPRlNBQV9BTkFMWVRJQ1NfUFVCIiwKICAgICAgICAiZGF0YWJhc2VfbmFtZV8xIjogIk9GU0FBX0FOQUxZVElDU19QVUIiLAogICAgICAgICJiaV9TZXJ2aWNlc18xIjpbImR2IiwicnBkIiwiYmlwdWJsaXNoZXIiXQogICAgICB9Cg== xxxxx
  1. 保留 LF(躲避他们)
> lf=$'\n'
> echo "xxxxx ##CONNECTION_DETAILS## xxxxx" | sed -e "s|##CONNECTION_DETAILS##|${CONNECTION_DETAILS//$lf/\\$lf}|g"
xxxxx CSAgewogICAgICAgICJjb25uZWN0aW9uX2
5hbWVfMSI6ICJPRlNBQV9BTkFMWVRJQ1NfUFVCIiwKICAgICAgICAi
ZGF0YWJhc2VfbmFtZV8xIjogIk9GU0FBX0FOQUxZVElDU19QVUIiLA
ogICAgICAgICJiaV9TZXJ2aWNlc18xIjpbImR2IiwicnBkIiwiYmlw
dWJsaXNoZXIiXQogICAgICB9Cg== xxxxx

更新

如果要在文本两边添加双引号:

> lf=$'\n'
> echo "xxxxx ##CONNECTION_DETAILS## xxxxx" | sed -e "s|##CONNECTION_DETAILS##|\"${CONNECTION_DETAILS//$lf/\\$lf}\"|g"
xxxxx "CSAgewogICAgICAgICJjb25uZWN0aW9uX2
5hbWVfMSI6ICJPRlNBQV9BTkFMWVRJQ1NfUFVCIiwKICAgICAgICAi
ZGF0YWJhc2VfbmFtZV8xIjogIk9GU0FBX0FOQUxZVElDU19QVUIiLA
ogICAgICAgICJiaV9TZXJ2aWNlc18xIjpbImR2IiwicnBkIiwiYmlw
dWJsaXNoZXIiXQogICAgICB9Cg==" xxxxx

答案2

您正在使用sedYAML 进行操作,尽管它非常灵活,但它可能是错误的工具。

我建议使用更合适的工具,例如jq对于 JSON(仅)或yq对于 JSON/YAML。

jq对于操作 JSON 来说已经很成熟了,yq当您还必须操作 YAML 时,它是一个可靠的对应物。

您没有显示太多内容,因此这是一个相当通用的示例(用作.config.connection_details要更新的值),但它可能很简单:

$ yq --inplace '.config.connection_details = {"connection_name_1": "OFSAA_ANALYTICS_PUB", "database_name_1": "OFSAA_ANALYTICS_PUB", "bi_Services_1":["dv","rpd","bipublisher"]}' dep.yaml

虽然这有效,但它看起来很像,sed并且遇到了与可能扰乱表达的角色相同的问题。

作为更好的选择,您可以将您的值作为单独的文档提供,并将其注入第一个文档中:

$ printf "%s" "${CONNECTION_DETAILS}" | yq eval-all --inplace 'select(fileIndex == 0).config.connection_details = select(fileIndex == 1)' dep.yaml -

由于yq使用的是 JSON 超集的 YAML,因此您可以向其提供 JSON 或 YAML,它仍然会加载它。

编辑:似乎有多个yqs,我在这个答案中使用 Mike Farah 的,有一个基于Python的作者:Andrey Kyslyuk,但语法似乎有所不同。

答案3

${CONNECTION_DETAILS}我建议将命令替换sed${CONNECTION_DETAILS//$'\n'}删除所有换行符。

相关内容