【问题标题】:jq: Getting two levels of keysjq:获取两级密钥
【发布时间】:2015-11-10 10:05:24
【问题描述】:

我有一些看起来像这样的 json 数据:

{
  "p": {
    "d": {
      "a" : {
        "r": "foo",
        "g": 1
      },
      "b": {
        "r": "bar",
        "g": 2
      }
    },
    "c": {
      "e": {
        "r": "baz",
        "g": 1
      }
    },
    ...
  }
}

我想要类似的东西:

{
  "d": [ 
    "a",
    "b"
  ],
  "c": [
    "e"
  ]
}

我可以用jq '.p|keys'得到“p”下第一级的键列表,用jq '.p|map(.|keys)'可以得到第二级的结构和键,但我不知道如何组合。

【问题讨论】:

    标签: jq


    【解决方案1】:

    使用map_values 而不是map 来映射JSON 对象的值,同时保留键:

    jq '.p | map_values(keys)'
    

    在低于 1.5 的 jq 版本上,未定义 map_values:相反,您可以使用 []|=

    jq '.p | . []|= keys'
    

    【讨论】:

    • 显然map_values 在我这里的版本(1.4)中不存在。
    • 试试jq '.p | . []|= keys'
    • 这正是我想要的。如果你把它变成一个答案,我会接受它。
    • 好吧,如果我没记错的话,map_values 在 jq 的标准库中被定义为 def map_values(f): . []|= f;,所以两个答案是等价的;第一个对您不起作用的原因是您使用的是旧版本的 jq。也就是说,我会将其附加到现有答案中。
    【解决方案2】:

    一般

    顶级键:

    curl -s https://crates.io/api/v1/crates/atty | jq '. |= keys'

    [
      "categories",
      "crate",
      "keywords",
      "versions"
    ]
    

    两级键:

    curl -s https://crates.io/api/v1/crates/atty | jq '.| map_values(keys)'

    {
      "crate": [
        "badges",
        "categories",
        "created_at",
        "description",
        "documentation",
        "downloads",
        "exact_match",
        "homepage",
        "id",
        "keywords",
        "links",
        "max_version",
        "name",
        "newest_version",
        "recent_downloads",
        "repository",
        "updated_at",
        "versions"
      ],
      "versions": [
        0,
        1,
        2,
        3,
        4,
        5,
        6,
        7,
        8,
        9,
        10,
        11,
        12,
        13,
        14,
        15,
        16
      ],
      "keywords": [
        0,
        1,
        2
      ],
      "categories": []
    }
    

    方法版本

    topLevelJsonKeys() {
     curl -s $1 | jq '. |= keys'
      # EXAMPLE: 
      # topLevelJsonKeys https://crates.io/api/v1/crates/atty
    }
    
    topLevelJsonKeys2() {
      curl -s $1 | jq '.| map_values(keys)'
      # EXAMPLE: 
      # topLevelJsonKeys2 https://crates.io/api/v1/crates/atty
    }
    

    【讨论】:

      【解决方案3】:

      这是一个使用 reducesetpath

      的解决方案
        .p
      | reduce keys[] as $k (
           .
         ; setpath([$k]; .[$k] | keys)
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-11-29
        • 2013-03-21
        • 1970-01-01
        相关资源
        最近更新 更多