我有以下JSON结构:
{
"host1": "$PROJECT1",
"host2": "$PROJECT2",
"host3" : "xyz",
"host4" : "$PROJECT4"
}
以及外壳中的以下环境变量:
PROJECT1="randomtext1"
PROJECT2="randomtext2"
PROJECT4="randomtext3"
我想检查每个键的值,如果它们有一个"$"字符,用它们各自的环境变量(已经存在于shell中(替换它们,以便用正确的环境变量呈现我的JSON模板。
我可以使用jq的--args
选项,但在我想要呈现的实际JSON模板中有很多变量。
我一直在尝试以下内容:
jq 'with_entries(.values as v | env.$v)
基本上将每个值作为一个变量,然后用env对象中的变量更新其值,但我似乎错过了一些理解。有没有一种简单的方法可以做到这一点?
编辑
多亏了这个问题的答案,我得以实现我的更大目标,其中一部分问题被问到
- 迭代对象中的每个值
- 检查其值,
- 如果它是一个字符串并且以字符"开头$">
- 使用该值使用同名的环境变量对其进行更新
- 如果是一个数组
- 使用该值检索同名的环境变量
- 用"作为分隔符,返回字符串数组
- 使用字符串数组更新值
- 如果它是一个字符串并且以字符"开头$">
jq 'with_entries(.value |= (if (type=="array") then (env[.[0][1:]] | split(",")) elif (type=="string" and startswith("$")) then (env[.[1:]]) else . end))'
您需要export
jq
:要查看的Bash变量
export PROJECT1="randomtext1"
export PROJECT2="randomtext2"
export PROJECT4="randomtext3"
然后你可以使用:
jq -n 'with_entries((.value | select(startswith("$"))) |= env[.[1:]])'
并得到:
{
"host1": "randomtext1",
"host2": "randomtext2",
"host3": "xyz",
"host4": "randomtext3"
}
printf
:
printf "%st" ${BASH_VERSINFO[@]}
3 2 57 1
您可能还会发现declare -p
很有帮助。
另请参阅https://github.com/stedolan/jq/wiki/Cookbook#arbitrary-字符串作为模板变量
这里有一个方法,它可以替换文件中的所有变量,而不管它们的嵌套级别如何。如果没有在环境中定义值,它会保持这些值的原样。在以下示例中,STREET未定义为环境变量,因此保持不变。
匹配的正则表达式(^\$[A-Z_-]+$(可以根据您的需要进行更改,例如用${}或{{}}定义的变量。
$ cat test.json
{
"name": "$NAME",
"address": [{
"street": "$STREET",
"other": "$not_matching"
}]
}
$ cat test.json | NAME=Joe jq 'walk( if type == "string" and test("^\$[A-Z_-]+$") then . |= env[.[1:]] // . else . end )'
{
"name": "Joe",
"address": [
{
"street": "$STREET",
"other": "$not_matching"
}
]
}
唯一的限制是它只替换完全匹配的值。对于https://$HOSTNAME/index.html
这样的值,它将不起作用。为此,请改用sed
。