我正在尝试设置JSON配置文件的层次结构,其中默认值可以在多个级别被覆盖。每个文件都是一组键/值对。其中有许多按功能以非字母顺序组织。
我找到了一种获取所需逻辑结果的方法,但是该方法以字母顺序排序,并且由于预期参数的数量,用户将难以清晰/迅速地查看该集合是否是他们想要在使用它之前。
有没有一种方法可以执行这种合并,替换匹配键上的值并保留顺序?
我有以下文件:
default.json:
[
{ "ParameterKey": "FirstStackName", "ParameterValue": "Production-App-Database" },
{ "ParameterKey": "SecondStackName", "ParameterValue": "Production-Directory" },
{ "ParameterKey": "ThirdStackName", "ParameterValue": "Production-VPC" },
{ "ParameterKey": "FourthStackName", "ParameterValue": "AMIFunctions" },
{ "ParameterKey": "FifthKeyName", "ParameterValue": "administrator" },
{ "ParameterKey": "SixthUserName", "ParameterValue": "admin" },
{ "ParameterKey": "SeventhPassword", "ParameterValue": "" }
]
environment.json:
[
{ "ParameterKey": "FirstStackName", "ParameterValue": "Development-App-Database" },
{ "ParameterKey": "SecondStackName", "ParameterValue": "Development-Directory" },
{ "ParameterKey": "ThirdStackName", "ParameterValue": "Development-VPC" },
{ "ParameterKey": "FifthKeyName", "ParameterValue": "developer" }
]
user.json:
[
{ "ParameterKey": "FifthKeyName", "ParameterValue": "jdoe" }
]
secure.json:
[
{ "ParameterKey": "SeventhPassword", "ParameterValue": "secretvalue" }
]
如果我运行此命令:
jq -s '.[3] + .[2] + .[1] + .[0] | unique_by(.ParameterKey)' default.json environment.json user.json secure.json
我得到一些有用的东西:
[
{
"ParameterKey": "FifthKeyName",
"ParameterValue": "jdoe"
},
{
"ParameterKey": "FirstStackName",
"ParameterValue": "Development-App-Database"
},
{
"ParameterKey": "FourthStackName",
"ParameterValue": "AMIFunctions"
},
{
"ParameterKey": "SecondStackName",
"ParameterValue": "Development-Directory"
},
{
"ParameterKey": "SeventhPassword",
"ParameterValue": "secretvalue"
},
{
"ParameterKey": "SixthUserName",
"ParameterValue": "admin"
},
{
"ParameterKey": "ThirdStackName",
"ParameterValue": "Development-VPC"
}
]
但是(想象60个参数)它不容易被正确地扫描,而我想要的是:
[
{ "ParameterKey": "FirstStackName", "ParameterValue": "Development-App-Database" },
{ "ParameterKey": "SecondStackName", "ParameterValue": "Development-Directory" },
{ "ParameterKey": "ThirdStackName", "ParameterValue": "Development-VPC" },
{ "ParameterKey": "FourthStackName", "ParameterValue": "AMIFunctions" },
{ "ParameterKey": "FifthKeyName", "ParameterValue": "jdoe" },
{ "ParameterKey": "SixthUserName", "ParameterValue": "admin" },
{ "ParameterKey": "SeventhPassword", "ParameterValue": "secretvalue" }
]
答案 0 :(得分:1)
unique_by
需要进行排序,因此最简单的方法是使用INDEX
(大写):
[INDEX(inputs[]; .ParameterKey)[]]
我在这里使用inputs
来避免-s选项的所有缺点,但请记住改用-n选项。
如果您的jq没有INDEX,则可以使用以下def:
def INDEX(s; f):
reduce s as $x (null; .[$x|f] = $x );
答案 1 :(得分:0)
最简单的方法是从键到值构建一个映射(依次组合所有输入源),然后返回并重新处理default.json
,应用生成的映射。
jq -n --slurpfile template default.json '
# generate an unordered key:value dictionary
([inputs | .[] | {(.ParameterKey): (.ParameterValue)}] | add) as $map |
# apply those pairs to the template to get its ordering
[ $template[0][] | {"ParameterKey": (.ParameterKey), "ParameterValue": ($map[.ParameterKey])} ]
' default.json environment.json user.json secure.json
...可以正确输出:
[
{
"ParameterKey": "FirstStackName",
"ParameterValue": "Development-App-Database"
},
{
"ParameterKey": "SecondStackName",
"ParameterValue": "Development-Directory"
},
{
"ParameterKey": "ThirdStackName",
"ParameterValue": "Development-VPC"
},
{
"ParameterKey": "FourthStackName",
"ParameterValue": "AMIFunctions"
},
{
"ParameterKey": "FifthKeyName",
"ParameterValue": "jdoe"
},
{
"ParameterKey": "SixthUserName",
"ParameterValue": "admin"
},
{
"ParameterKey": "SeventhPassword",
"ParameterValue": "secretvalue"
}
]
...保留default.json
的顺序。
如果您坚持具有这样的空格,则一种实现方法是通过以下内容通过管道传递上述内容:
#!/usr/bin/env bash
shopt -s extglob
pieces=( )
while read -r line; do
case $line in
"["|"]") printf '%s\n' "$line";;
*(' ')"}"?(,)) printf '%2s %-35s %s %2s\n' "${pieces[@]}" "$line"; pieces=( );;
*) pieces+=( "$line" )
esac
done
上面的内容仅更改空白,不识别除换行符以外的任何分隔符,请注意;因此,其输出在语义上应始终与输入相同。参见https://ideone.com/EI0RuJ,作为该代码在实践中工作的演示,输出为:
[
{ "ParameterKey": "FirstStackName", "ParameterValue": "Development-App-Database" },
{ "ParameterKey": "SecondStackName", "ParameterValue": "Development-Directory" },
{ "ParameterKey": "ThirdStackName", "ParameterValue": "Development-VPC" },
{ "ParameterKey": "FourthStackName", "ParameterValue": "AMIFunctions" },
{ "ParameterKey": "FifthKeyName", "ParameterValue": "jdoe" },
{ "ParameterKey": "SixthUserName", "ParameterValue": "admin" },
{ "ParameterKey": "SeventhPassword", "ParameterValue": "secretvalue" }
]