如何删除除 jq 之外的所有键?

Posted

技术标签:

【中文标题】如何删除除 jq 之外的所有键?【英文标题】:How do I remove all keys except one with 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',但这会提取值,而不是保留对象。

【问题讨论】:

【参考方案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
)

【讨论】:

以上是关于如何删除除 jq 之外的所有键?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 JQ 删除所有嵌套键

如何从表中删除除前两个和最后一个之外的所有行?

如何删除 Core Data 存储中除一个对象之外的所有对象?

如何删除除一个之外具有相同id的所有元素? [复制]

如何使用 Ant 删除除最新的 2 个文件之外的所有文件

如何删除除 Markdown 之外的所有文件中的尾随空格?