我有一个小脚本
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 } ]'
输出(使用jq
with-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
在本例中也可以使用。
我开始将此处文档视为另一种类型的字符串引用。由于不使用单引号或双引号来引用整个字符串,因此通常不需要使用反引号对其进行转义。