我的目标是获取一组密钥对的每个值,并将每个密钥对插入另一个文件中。我可以逐行完成这项工作,但是有更清晰的方法可以一次性添加它们吗?
我有一个aws查询的结果,它给了我一个名为vpc.json
的文件(删除了敏感信息);
[
{
"Description": "Client VpcId",
"OutputKey": "VpcId",
"OutputValue": "vpc-a12345"
},
{
"OutputKey": "ServiceSubnet1",
"OutputValue": "subnet-b12345"
},
{
"OutputKey": "PublicSubnet1",
"OutputValue": "subnet-c12345"
},
{
"OutputKey": "ServiceSubnet0",
"OutputValue": "subnet-d12345"
},
{
"OutputKey": "PublicSubnet0",
"OutputValue": "subnet-e12345"
}
]
并且我希望每个值最终都在parameters.json
,其中已经有一堆其他密钥对,最终文件看起来像;
[
{
...
},
{
"ParameterKey": "VpcId",
"ParameterValue": "vpc-a12345"
},
{
"ParameterKey": "ServiceSubnet0",
"ParameterValue": "subnet-b12345"
},
{
"ParameterKey": "ServiceSubnet1",
"ParameterValue": "subnet-c12345"
},
{
"ParameterKey": "PublicSubnet0",
"ParameterValue": "subnet-d12345"
},
{
"ParameterKey": "PublicSubnet1",
"ParameterValue": "subnet-e12345"
}
]
现在我可以轻松地"使用以下代码实现此目的。这将是VpcId
对所需的片段,这意味着我必须复制x5,每个密钥对一个。
代码检查密钥对是否已经存在,如果不存在则添加密钥对(必要时因为它需要向后兼容旧文件)。然后它从vpc文件中获取相关值并将其放在参数文件中。
if ! grep -q "VpcId" parameters.json
then
jq --argjson obj '{ "ParameterKey": "VpcId", "ParameterValue": "" }' '. += [$obj]' <parameters.json | sponge parameters.json
fi
keyVpc=$(jq -r '.[] | select(.OutputKey=="VpcId") | .OutputValue' < vpc.json)
jq --arg keyVpc "$keyVpc" '(.[] | select(.ParameterKey == "VpcId") | .ParameterValue) |= $keyVpc' ${parameters.json | sponge parameters.json
我必须想象有一个更好的方法来做到这一点,不需要5个相同的三行副本。键将始终是相同的名称,但值将更改。
答案 0 :(得分:3)
为清楚起见,我们首先定义一个jq辅助函数来修改键/值对:
def munge: {ParameterKey: .OutputKey, ParameterValue: .OutputValue};
我们还假设vpc.json的内容可用作jq变量$ vpc - 这可以完成(例如)如下所示。
然后可以通过此jq过滤器执行更新:
. + (($vpc | map(munge)) - .)
以下调用是几种可能之一,但其优点是不需要最新的jq版本:
jq -f vpc.jq --argfile vpc vpc.json parameters.json
根据具体要求,可能会有更有效的变化。例如,如果键/值对的顺序不重要:
(. + ($vpc | map(munge))) | unique
相反,为了避免重复($ vpc | map(munge)),同时保留排序:
reduce ($vpc[] | munge) as $new
(.; if index($new) then . else . + [$new] end)