从 JQ 中的复杂嵌套 JSON 数据中选择
Selecting from complex nested JSON data in JQ
我有 JSON 这样的数据:
{
"profiles": {
"auto_scaler": [
{
"auto_scaler_group_name": "myasg0",
"auto_scaler_group_options": {
":availability_zones": ["1a", "1b", "1c"],
":max_size": 1,
":min_size": 1,
":subnets": ["a", "b", "c"],
":tags": [
{":key": "Name", ":value": "app0" },
{":key": "env", ":value": "dev" },
{":key": "role", ":value": "app" },
{":key": "domain", ":value": "example.com" },
{":key": "fonzi_app", ":value": "true"},
{":key": "vpc", ":value": "nonprod"}
]
},
"dns_name": "fonz1"
},
{
"auto_scaler_group_name": "myasg1",
"auto_scaler_group_options": {
":availability_zones": ["1a", "1b", "1c"],
":max_size": 1,
":min_size": 1,
":subnets": ["a", "b", "c"],
":tags": [
{":key": "Name", ":value": "app1" },
{":key": "env", ":value": "dev" },
{":key": "role", ":value": "app" },
{":key": "domain", ":value": "example.com" },
{":key": "bozo_app", ":value": "true"},
{":key": "vpc", ":value": "nonprod"}
]
},
"dns_name": "bozo1"
}
]
}
}
我想先写一个 jq 查询 select .profiles.auto_scaler
的数组中的哈希元素,其 .auto_scaler_group_options.tags
的哈希数组包含包含“:key
”键,其值包含“fonzi
”和一个“:value
”键,其值恰好true
然后 return 键的值 dns_name
.
在示例中,查询将简单地 return "fonz1"
.
有谁知道如何做到这一点,如果可能的话,使用 jq?
您可以按数量或方式查找 JSON,
- 通过检查 属性 是否存在
- 通过使用 [属性] 语法,
- 'property' 对象语法
对于你的情况,这里有一个小样本,你可以进一步查找数组并查看
containing a "key" key whose value contains EEE and a "value" key
whose value is exactly FFF
for(var k=0; k < p['AAA']['BBB'].length;k++){
console.log(p['AAA']['BBB'][k])
}
其中 p 是 JSON 对象。
希望对您有所帮助
简而言之,是的。
长:
.profiles.auto_scaler[]
| .dns_name as $name
| .auto_scaler_group_options
| select( any(.[":tags"][];
(.[":key"] | index("fonzi")) and (.[":value"] == "true")) )
| $name
上面的输出是:
"fonz1"
这里的技巧是在更深入地研究 "complex nested JSON".
之前提取候选 .dns_name
另一种选择
如果您的 jq 没有 any
,您可以(在这种特殊情况下)通过将上面的 select
表达式替换为:
来摆脱它
select( .[":tags"][]
| (.[":key"] | index("fonzi")) and (.[":value"] == "true") )
不过请注意,这两个表达式的语义略有不同。 (作业练习:有什么区别?)
如果你的 jq 没有 any
并且你想要 any
的语义,那么你可以轻松地自己推出,或者简单地升级 :-)
我有 JSON 这样的数据:
{
"profiles": {
"auto_scaler": [
{
"auto_scaler_group_name": "myasg0",
"auto_scaler_group_options": {
":availability_zones": ["1a", "1b", "1c"],
":max_size": 1,
":min_size": 1,
":subnets": ["a", "b", "c"],
":tags": [
{":key": "Name", ":value": "app0" },
{":key": "env", ":value": "dev" },
{":key": "role", ":value": "app" },
{":key": "domain", ":value": "example.com" },
{":key": "fonzi_app", ":value": "true"},
{":key": "vpc", ":value": "nonprod"}
]
},
"dns_name": "fonz1"
},
{
"auto_scaler_group_name": "myasg1",
"auto_scaler_group_options": {
":availability_zones": ["1a", "1b", "1c"],
":max_size": 1,
":min_size": 1,
":subnets": ["a", "b", "c"],
":tags": [
{":key": "Name", ":value": "app1" },
{":key": "env", ":value": "dev" },
{":key": "role", ":value": "app" },
{":key": "domain", ":value": "example.com" },
{":key": "bozo_app", ":value": "true"},
{":key": "vpc", ":value": "nonprod"}
]
},
"dns_name": "bozo1"
}
]
}
}
我想先写一个 jq 查询 select .profiles.auto_scaler
的数组中的哈希元素,其 .auto_scaler_group_options.tags
的哈希数组包含包含“:key
”键,其值包含“fonzi
”和一个“:value
”键,其值恰好true
然后 return 键的值 dns_name
.
在示例中,查询将简单地 return "fonz1"
.
有谁知道如何做到这一点,如果可能的话,使用 jq?
您可以按数量或方式查找 JSON,
- 通过检查 属性 是否存在
- 通过使用 [属性] 语法,
- 'property' 对象语法
对于你的情况,这里有一个小样本,你可以进一步查找数组并查看
containing a "key" key whose value contains EEE and a "value" key whose value is exactly FFF
for(var k=0; k < p['AAA']['BBB'].length;k++){
console.log(p['AAA']['BBB'][k])
}
其中 p 是 JSON 对象。
希望对您有所帮助
简而言之,是的。
长:
.profiles.auto_scaler[]
| .dns_name as $name
| .auto_scaler_group_options
| select( any(.[":tags"][];
(.[":key"] | index("fonzi")) and (.[":value"] == "true")) )
| $name
上面的输出是:
"fonz1"
这里的技巧是在更深入地研究 "complex nested JSON".
之前提取候选 .dns_name另一种选择
如果您的 jq 没有 any
,您可以(在这种特殊情况下)通过将上面的 select
表达式替换为:
select( .[":tags"][]
| (.[":key"] | index("fonzi")) and (.[":value"] == "true") )
不过请注意,这两个表达式的语义略有不同。 (作业练习:有什么区别?)
如果你的 jq 没有 any
并且你想要 any
的语义,那么你可以轻松地自己推出,或者简单地升级 :-)