使用jq玩了几个小时后,我需要你帮助选择和合并对象。
我有这种JSON:
{
"cluster-1": {
"vhosts": {
"vhost_aaa": {
"postgresql": {
"bdd1": {
"db_aaa": {
"user_aaa": {
"password": "xxx"
}
}
},
"bdd2": {
"db_aaa": {
"user_aaa": {
"password": "xxx"
}
}
}
}
}
}
},
"cluster-2": {
"vhosts": {
"vhost_bbb": {
"postgresql": {
"bdd1": {
"db_bbb": {
"user_bbb": {
"password": "xxx"
},
"user_bbb_ro": {
"password": "xxx"
}
}
}
}
},
"vhost_ccc": {
"postgresql": {
"bdd1": {
"db_ccc": {
"user_ccc": {
"password": "xxx"
}
}
}
}
}
}
}
}
这是一个很深的JSON告诉我,在 cluster-x 上有vhosts( vhosts_xxx )可能会使用某种数据库(这里是 postgresql )由服务器(此处为 bdd1 或 bdd2 )托管,其中包含我想要创建的数据库( db_xxx )具有凭据详细信息的用户( user_xxx )。哇!
我的目标是选择部分数据来执行特定操作,因此对于数据库服务器,我希望所有操作都在同一服务器上执行,因此这是我尝试使用jq生成的内容:
"bdd1": {
"db_aaa": {
"user_aaa": {
"password": "xxx"
}
},
"db_bbb": {
"user_bbb": {
"password": "xxx"
},
"user_bbb_ro": {
"password": "xxx"
}
},
"db_ccc": {
"user_ccc": {
"password": "xxx"
}
}
},
"bdd2": {
"db_aaa": {
"user_aaa": {
"password": "xxx"
}
}
}
使用此过滤器(..|.vhosts?|..|.postgresql?)|objects
,我可以隔离我需要的数据。
{
"bdd1": {
"db_aaa": {
"user_aaa": {
"password": "xxx"
}
}
},
"bdd2": {
"db_aaa": {
"user_aaa": {
"password": "xxx"
}
}
}
}
{
"bdd1": {
"db_bbb": {
"user_bbb": {
"password": "xxx"
},
"user_bbb_ro": {
"password": "xxx"
}
}
}
}
{
"bdd1": {
"db_ccc": {
"user_ccc": {
"password": "xxx"
}
}
}
}
下一步是合并按 bddx 分组的所有这些数据。 欢迎任何帮助或建议:)
答案 0 :(得分:0)
您可以使用to_entries
将对象转换为属性/值的键/值对数组。然后,您可以将这些对分组以构建结果。
[..|.vhosts?|..|.postgresql?|objects|to_entries[]]
| reduce group_by(.key)[] as $g ({};
.[$g[0].key] = [$g[].value]
)
这产生以下结果:
{
"bdd1": [
{
"db_aaa": {
"user_aaa": { "password": "xxx" }
}
},
{
"db_ccc": {
"user_ccc": { "password": "xxx" }
}
},
{
"db_bbb": {
"user_bbb": { "password": "xxx" },
"user_bbb_ro": { "password": "xxx" }
}
}
],
"bdd2": [
{
"db_aaa": {
"user_aaa": { "password": "xxx" }
}
}
]
}
答案 1 :(得分:0)
避免使用..
可能更安全(即更强大)。如果数据按照您的指示进行结构化,则以下过滤器适合执行任务的“选择”部分:
to_entries[] | .value.vhosts
| to_entries[] | .value.postgresql // empty
然后你可以按照Jeff建议的那样使用它:
[to_entries[] | .value.vhosts
| to_entries[] | .value.postgresql // empty
| to_entries[]]
| group_by(.key)
| reduce .[] as $g ({}; .[$g[0].key] = [$g[].value] )
答案 2 :(得分:0)
以下是reduce Sylvain使用* object multiplication过滤的另一种解决方案
reduce ((..|.vhosts?|..|.postgresql?)|objects) as $i({}; . *= $i)
使用它生成的样本数据
{
"bdd1": {
"db_aaa": {
"user_aaa": {
"password": "xxx"
}
},
"db_bbb": {
"user_bbb": {
"password": "xxx"
},
"user_bbb_ro": {
"password": "xxx"
}
},
"db_ccc": {
"user_ccc": {
"password": "xxx"
}
}
},
"bdd2": {
"db_aaa": {
"user_aaa": {
"password": "xxx"
}
}
}
}