我有以下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))'
3条答案
按热度按时间bhmjp9jg1#
您需要
export
Bash变量才能被jq
看到:那么你可以这样说:
并得到:
8ulbf1ek2#
导出大量shell变量可能不是一个好主意,也不能解决数组值变量的问题。因此,按照将variable = value的细节打印到一个文件中,然后将该文件与模板组合的思路来考虑可能是一个好主意。这很容易做到,互联网上的例子比比皆是,SO上的例子也可能如此。例如,您可以像这样使用
printf
:您可能还会发现
declare -p
很有用。另请参见www.example.comhttps://github.com/stedolan/jq/wiki/Cookbook#arbitrary-strings-as-template-variables
fv2wmkja3#
下面是一个替换文件中所有变量的方法,而不管它们的嵌套级别如何。如果它们没有在环境中定义,它会保持它们的值不变。在下面的示例中,STREET没有定义为环境变量,因此保持不变。
匹配的正则表达式(^$[A-Z_-]+$)可以根据您的需要进行更改,例如使用${}或{{}}定义的变量。
唯一的限制是它只能替换完全匹配的值。它不适用于
https://$HOSTNAME/index.html
这样的值。为此,请使用sed
。