如何在linux中使用json字符串作为变量

如何在linux中使用json字符串作为变量

我有一个小脚本

ABC=100000
DFG=600000

JSON="[{"Address":"$ABC","Backup":false,"name":"$ABC:11011","port":6745,"targetId":"$DFG","weight":1}]"

echo $JSON

我得到的输出为

[{Address:$ABC,Backup:false,name:$ABC:11011,port:6745,targetId:$DFG,weight:1}]

在这种情况下,有人可以帮我吗 TIA

答案1

您的双引号字符串包含双引号。

您可以转义所有要保留的内部引号:

JSON="[{\"Address\":\"$ABC\",\"Backup\":false,\"name\":\"$ABC:11011\",\"port\":6745,\"targetId\":\"$DFG\",\"weight\":1}]"

您可以使用单引号字符串,在变量所在的位置中断(这很难阅读):

JSON='[{"Address":"'"$ABC"'","Backup":false,"name":"'"$ABC"':11011","port":6745,"targetId":"'"$DFG"'","weight":1}]'

您可以将 printf 与单引号格式字符串一起使用:

printf -v JSON '[{"Address":"%s","Backup":false,"name":"%s:11011","port":6745,"targetId":"%s","weight":1}]' "$ABC" "$ABC" "$DFG"

或者,使用 JSON 处理工具来处理具有变量值的任何边缘情况:

JSON=$(
  jq -n -c --arg a "$ABC" --arg b "$DFG" '[{
    Address: $a, 
    Backup: false,
    name: ($a + ":11011"),
    port: 6745,
    targetId: $b,
    weight: 1
  }]'
)
echo "$JSON"

输出

[{"Address":"100000","Backup":false,"name":"100000:11011","port":6745,"targetId":"600000","weight":1}]

答案2

请注意,将 shell 变量的值注入 JSON 文档可能会导致 JSON 字符串损坏,因为缺少编码特殊值。最好(更可靠)使用 JSON 感知工具来创建 JSON 文档并插入所需的值。

使用jq简单的模板编写 JSON 文档:

ABC=100000
DFG=600000

jq -n \
    --arg Address  "$ABC" \
    --arg targetId "$DFG" \
    --arg name     "$ABC:11011" \
    '[ $ARGS.named + { Backup: false, port: 6745, weight: 1 } ]'

输出(使用jqwith-c获得“紧凑”输出):

[
  {
    "Address": "100000",
    "targetId": "600000",
    "name": "100000:11011",
    "Backup": false,
    "port": 6745,
    "weight": 1
  }
]

这将创建一个由单个元素组成的数组,这是一个静态对象,我们向其中添加一些带有值的命名字段。字段名称(键)及其值--arg key value在命令行上重复使用。

由于我们使用jq它来创建 JSON 文档,因此如果ABC持有类似的值100 "My Road"(即带有嵌入的引号、换行符或制表符等),这仍然有效。

答案3

您还可以使用此处文档以扩展形式的 JSON 结构填充变量,以便人们更容易阅读和维护,并将 shell 变量值替换到中间,而无需使用大量反斜杠来转义引号字符:

f_name=Sotto
l_name=Voce
JSON=$(cat - <<EOJSON
{
  "first_name": "${f_name}",
  "last_name": "${l_name}",
  "full_name": "${f_name} ${l_name}"
}
EOJSON
)

然后echo "${JSON}"echo "$JSON"输出:

{
  "first_name": "Sotto",
  "last_name": "Voce",
  "full_name": "Sotto Voce"
}

我的个人风格在变量名周围使用大括号,但这里不需要。$f_name在本例中也可以使用。

我开始将此处文档视为另一种类型的字符串引用。由于不使用单引号或双引号来引用整个字符串,因此通常不需要使用反引号对其进行转义。

相关内容