简体   繁体   English

从JQ中的复杂嵌套JSON数据中选择

[英]Selecting from complex nested JSON data in JQ

I have JSON data like this: 我有这样的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"
      }
    ]
  }
}

I want to write a jq query to firstly select the Hash element in the Array at .profiles.auto_scaler whose Array of Hashes at .auto_scaler_group_options.tags contains Hashes containing a " :key " key whose value contains " fonzi " and a " :value " key whose value is exactly true and then return the value of the key dns_name . 我想编写一个jq查询,首先在.profiles.auto_scaler的Array中选择其Hash元素,其在.auto_scaler_group_options.tags的hash数组包含的哈希表包含一个“ :key ”键,其值包含fonzi ”和一个“ :value完全 true的密钥,然后返回密钥dns_name的值。

In the example, the query would simply return "fonz1" . 在该示例中,查询将仅返回"fonz1"

Does anyone know how to do this, if it is possible, using jq? 有谁知道如何使用jq做到这一点?

In brief, yes. 简而言之,是的。

In long: 总而言之:

.profiles.auto_scaler[]
| .dns_name as $name
| .auto_scaler_group_options
| select( any(.[":tags"][];
             (.[":key"] | index("fonzi")) and (.[":value"] == "true")) )
| $name

The output of the above is: 上面的输出是:

"fonz1"

The trick here is to extract the candidate .dns_name before diving more deeply into your "complex nested JSON". 这里的技巧是在更深入地研究“复杂的嵌套JSON”之前提取候选.dns_name。

An alternative 替代

If your jq does not have any , you could (in this particular case) get away without it by replacing the select expression above with: 如果您的jq没有any ,您可以(在这种情况下)通过将上面的select表达式替换为:

 select( .[":tags"][]
         | (.[":key"] | index("fonzi")) and (.[":value"] == "true") )

Be warned, though, that the semantics of the two expressions are slightly different. 但是请注意,两个表达式的语义略有不同。 (Homework exercise: what is the difference?) (家庭作业:有什么区别?)

If your jq doesn't have any and if you want the semantics of any , then you could easily roll your own, or simply upgrade :-) 如果您的jq没有any ,并且您想要any语义,那么您可以轻松地自己滚动或简单地升级:-)

You can lookup JSON in number or ways , 您可以通过多种方式查询JSON,

  1. by checking property exists or not 通过检查属性是否存在
  2. by using [property] syntax, 通过使用[property]语法,
  3. 'property' in object syntax 对象语法中的“属性”

for your case , here's a small sample , further you can lookup on array and see 对于您的情况,这是一个小样本,此外,您可以在数组上查找并查看

containing a "key" key whose value contains EEE and a "value" key whose value is exactly FFF 包含一个其值包含EEE的“键”键和一个其值正好为FFF的“值”键

for(var k=0; k < p['AAA']['BBB'].length;k++){  
   console.log(p['AAA']['BBB'][k]) 
}

where p is JSON object. 其中p是JSON对象。

Hope that helps 希望能有所帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM