如何用 jq 中各自的 shell 变量替换 JSON 字典中的值?

How to replace values in a JSON dictionary with their respective shell variables in jq?

我有以下 JSON 结构:

{
  "host1": "$PROJECT1",
  "host2": "$PROJECT2",
  "host3" : "xyz",
  "host4" : "$PROJECT4"
}

以及shell中的以下环境变量:

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 Bash 变量才能被 jq 看到:

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"
}

导出大量 shell 变量可能不是一个好主意,并且不能解决数组值变量的问题。因此,考虑将 variable=value 详细信息打印到文件,然后将该文件与模板组合起来可能是个好主意。这很容易做到,互联网上的例子比比皆是,可能在 SO 上也有。例如,您可以像这样使用 printf

printf "%s\t" ${BASH_VERSINFO[@]}
3   2   57  1   

您可能还会发现 declare -p 有帮助。

另见 https://github.com/stedolan/jq/wiki/Cookbook#arbitrary-strings-as-template-variables