【问题标题】:filter an object based on properties of its values根据对象值的属性过滤对象
【发布时间】:2018-04-07 10:26:15
【问题描述】:

我正在尝试使用 jq 来过滤 json 块。我需要保留完整的结构,但过滤掉“不可配置”的子 json 块。

{
  "properties": {
    ".properties.backup_options": {
      "type": "selector",
      "configurable": true,
      "credential": false,
      "value": "disable",
      "optional": false
    },
    ".properties.backup_options.enable.cron_schedule": {
      "type": "string",
      "configurable": true,
      "credential": false,
      "value": null,
      "optional": false
    },
    ".properties.backup_options.enable.backup_all_masters": {
      "type": "boolean",
      "configurable": true,
      "credential": false,
      "value": true,
      "optional": false
    },
    ".properties.backups": {
      "type": "selector",
      "configurable": false,
      "credential": false,
      "value": "disable",
      "optional": false
    },
    ".properties.backups.enable.endpoint_url": {
      "type": "string",
      "configurable": false,
      "credential": false,
      "value": null,
      "optional": true
    }
}

我已经能够过滤掉cat input.json | jq '.properties[] | select(.configurable==true)',但是这会丢失原始结构。

奖励标记还可以过滤掉子块中的一些字段,即删除凭据和类型行。

所以想要的输出是:

{
  "properties": {
    ".properties.backup_options": {
      "configurable": true,
      "value": "disable",
      "optional": false
    },
    ".properties.backup_options.enable.cron_schedule": {
      "configurable": true,
      "value": null,
      "optional": false
    },
    ".properties.backup_options.enable.backup_all_masters": {

      "configurable": true,
      "value": true,
      "optional": false
    }       
}

我是否需要嵌套多个 jq 语句来实现这一点?分解并重建?帮助(这已经花费了太多时间尝试不同的组合和教程)。

【问题讨论】:

    标签: json filter jq


    【解决方案1】:

    因此,您实际上是在获取一个对象并选择要保留的属性(或要删除的属性)。只需选择它们。

    我们正在更新properties 对象,因此请更新并选择(保留)所需的属性。过滤后,绘制出要保留在结果中的属性:

    $ jq '.properties |=
    with_entries(select(.value.configurable)
      | .value |= {configurable,value,optional}
    )' input.json
    

    【讨论】:

    • 我原以为 map_values(select(.configurable)) 可以工作,但可惜没有。 ://
    • 谢谢!我向JQ大师鞠躬。显然,我需要深入了解 JQ...
    【解决方案2】:

    这个过滤器会给你"configurable": true的属性

     .properties |= reduce keys[] as $k (.; 
         if .[$k].configurable 
         then . 
         else delpaths([[$k]]) end
      ) 
    

    Try it online at jqplay.org

    此过滤器演示了如何将属性进一步细化为键子集:

     .properties |= reduce keys[] as $k (.; 
         if   .[$k].configurable 
         then .[$k] |= {configurable,value,optional} 
         else delpaths([[$k]]) end
     )
    

    样本输出

    {
      "properties": {
        ".properties.backup_options": {
          "configurable": true,
          "value": "disable",
          "optional": false
        },
        ".properties.backup_options.enable.cron_schedule": {
          "configurable": true,
          "value": null,
          "optional": false
        },
        ".properties.backup_options.enable.backup_all_masters": {
          "configurable": true,
          "value": true,
          "optional": false
        }
      }
    }
    

    Try it online at jqplay.org

    使用辅助函数,例如

    def objmap(cond;update): reduce keys[] as $k (.; 
       if .[$k]|cond then .[$k]|=update else delpaths([[$k]]) end
    );
    

    过滤器可以写成

    .properties |= objmap(.configurable; .)
    

    .properties |= objmap(.configurable; {configurable,value,optional})
    

    【讨论】:

    • 谢谢!我向JQ大师鞠躬。显然,我需要深入了解 JQ...
    • jq 很深,我只是一个谦虚的学生。我发现jq source 对学习很有帮助,尤其是builtin.jq。在jq cookbookrosettacode 上也有很多很好的信息。如果您想了解更多信息,它们非常值得您花时间。
    猜你喜欢
    • 2015-05-30
    • 2018-12-25
    • 1970-01-01
    • 2023-03-12
    • 2017-03-19
    • 1970-01-01
    • 2018-07-06
    • 2016-05-12
    • 1970-01-01
    相关资源
    最近更新 更多