如何按名称过滤键,然后使用 jq 访问嵌套对象

Posted

技术标签:

【中文标题】如何按名称过滤键,然后使用 jq 访问嵌套对象【英文标题】:How to filter keys by name, then access nested object using jq 【发布时间】:2018-11-24 16:02:47 【问题描述】:

这里是 jq 新手,正在努力解决以下问题:

我有以下 json,需要根据关键字过滤键并打印出整个对象(不仅仅是键)或某些键/值对。注意 JSON 的嵌套对象结构,这是有意的。


  "timers": 
    "timerWithAKeywordAPlusBlah": 
      "count": 1,
      "max": 0,
      "min": 0      
    ,
    "timerWithAKeywordB": 
      "count": 2,
      "max": 0
    ,
    "timerWithAKeywordAPlusBlahBlah": 
      "count": 2385,
      "max": 2,
      "min": 1         
    
  

期望的输出:

"timerWithAKeywordAPlusBlah": 
  "count": 1,
  "max": 0,
  "min": 0
,
"timerWithAKeywordAPlusBlahBlah": 
  "count": 2385,
  "max": 2,
  "min": 1

我尝试过的事情:

我可以打印出键名,但不知道如何访问整个对象。

cat timers.json| jq '.timers | keys[] | select(contains("KeywordA")) '

【问题讨论】:

输入 json 无效:不能重复 timerWithAKeywordA .timers 应该是一个对象数组吗?您希望输出是有效的 JSON 吗? @RomanPerekhrest 谢谢,这是一个手动构建的示例,我忽略了键名的唯一性约束。更新了描述以反映这一点。 @peak 这是我正在使用的 json 的近似结构。 timers 只是包含各种计时器对象的对象之一。 我的答案已相应更新。 【参考方案1】:

在此响应中,我将假设您希望输出为有效的 JSON。如果您希望输出采用其他形式,您可以简单地添加一些额外的过滤器。

无论如何,诀窍是选择对象,而不是键,如下所示:

.timers
| with_entries( select(.key|contains("KeywordA") ) )

使用您的(修改后的)输入,这会产生:


  "timerWithAKeywordAPlusBlah": 
    "count": 1,
    "max": 0,
    "min": 0
  ,
  "timerWithAKeywordAPlusBlahBlah": 
    "count": 2385,
    "max": 2,
    "min": 1
  

然后您可以提取最终需要的任何细节。

【讨论】:

非常感谢您的详细回复。不知道为什么,但即使对象的键名与搜索关键字不匹配,该命令也会返回所有对象。但是您的命令使我看到了一篇关于将 json 格式转换为更易于使用的格式的文章。所以,我最终得到了以下结果,这可能有点矫枉过正,但它确实完成了工作:cat timers.json | jq '.timers | to_entries | map(timer: .key, count: .value.count, max: .value.max, min: .value.min) | .[] | select(.timer | contains("KeywordA"))'

以上是关于如何按名称过滤键,然后使用 jq 访问嵌套对象的主要内容,如果未能解决你的问题,请参考以下文章

当从扩展符号访问对象时如何访问 Javascript 对象的嵌套按名称属性...?

JQ 过滤嵌套对象中的字段

使用 jq 展平嵌套的 JSON

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

JQ:过滤键

基于 n 嵌套数组按名称过滤