【问题标题】:How do I remove all keys except one with jq?如何删除除 jq 之外的所有键?
【发布时间】:2015-03-06 10:49:53
【问题描述】:

给定一个对象列表,其中包含许多我不想要的键:

[{
    "name": "Alice",
    "group": "Admins",
    "created": "2014"
}, {
    "name": "Bob",
    "group": "Users",
    "created": "2014"
}]

如何过滤这些对象以仅包含我想要的键?

[{
    "name": "Alice"
}, {
    "name": "Bob"
}]

我尝试过jq '.[].name',但这会提取值,而不是保留对象。

【问题讨论】:

    标签: json key filtering jq


    【解决方案1】:

    您可以使用map() 函数过滤任意键:

    jq 'map({name: .name})'
    

    更新

    @WilfredHughes建议:以上过滤器可简写如下:

    jq 'map({name})'
    

    【讨论】:

    • 啊,完美!您甚至可以将其缩短为 jq 'map({name})'
    • 或者jq '{name}',如果输入是一个字典。
    【解决方案2】:

    如果您知道不想要的密钥,您可以使用mapdel

    jq 'map(del (.group) | del (.created))'
    

    【讨论】:

    • 回答很好,但如果有很多键,那么del 不是好主意
    • 是的,但主题标题表明这是要求 - 尽管文字含糊不清
    • 我怕我有很多key,所以我想加入白名单,而不是黑名单。我已经更新了标题以澄清。
    • 没问题,你应该接受另一个答案
    • 短一点:map(del(["group","created"])),虽然这只适用于黑名单
    【解决方案3】:

    没有map函数的另一种解决方案:

    jq '[.[] | {name: .name}]'
    

    【讨论】:

      【解决方案4】:

      接受的答案(map)和@mauricio-tranjano 的等效答案实际上会将指定的密钥添加到尚未拥有它的对象中。如果这不是您想要的行为,请考虑使用has(_),例如:

      $ jq -c 'map( if has("a") then {a} else {} end )'
      

      输入:

      [{id:1,a:1}, {id:2}]
      

      输出:

      [{"a":1},{}]
      

      【讨论】:

        【解决方案5】:

        这将允许保留一组字段(由正则表达式匹配)。

        map(
          to_entries
          |map(select(.key|test("^(name)$")))
          |from_entries
        )
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-03-14
          • 1970-01-01
          • 2020-06-23
          • 2017-06-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多