用jq删除与键匹配的对象和数组 [英] Delete objects and arrays with jq which match a key

查看:233
本文介绍了用jq删除与键匹配的对象和数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下内容的JSON:

I have a JSON with the following content:

{
  "data": [
    {
      "name": "Test",
      "program": {
        "publicAccess": "--------",
        "externalAccess": false,
        "userGroupAccesses": [
          {
            "access": "r-------"
          },
          {
            "access": "rw------"
          }
        ],
        "id": "MmBqeMLIC2r"
      },
      "publicAccess": "rw------"
    }
  ]
}

我想(递归)删除与publicAccessuserGroupAccesses匹配的所有键,以便我的JSON像这样:

And I want to delete all keys (recursively) which match publicAccess or userGroupAccesses, so that my JSON looks like this:

{
  "data": [
    {
      "name": "Test",
      "program": {
        "externalAccess": false,
        "id": "MmBqeMLIC2r"
      }
    }
  ]
}

我已经从

I've copied jq's builtin walk function from source.

# Apply f to composite entities recursively, and to atoms
def walk(f):
  . as $in
  | if type == "object" then
      reduce keys[] as $key
        ( {}; . + { ($key):  ($in[$key] | walk(f)) } ) | f
  elif type == "array" then map( walk(f) ) | f
  else f
  end;

# My Code
walk(if (type == "object" and .publicAccess)
        then del(.publicAccess)
     elif (type == "array" and .userGroupAccesses)
        then del(.userGroupAccesses)
     else
       .
end )

给我jq: error (at <stdin>:2622): Cannot index array with string "userGroupAccesses".另外,如果我使用.userGroupAccesses[]-如何获得结果?

Gives me jq: error (at <stdin>:2622): Cannot index array with string "userGroupAccesses". Also if I use .userGroupAccesses[] - How do I get the result?

jqplay上的代码段: https://jqplay.org/s/1m7wAeHMTu

Snippet on jqplay: https://jqplay.org/s/1m7wAeHMTu

推荐答案

您的问题是,当type == "array"为true时,.将是一个数组,因此.userGroupAccesses将不起作用.您想要做的只是关注.是对象的情况.在呼叫walk时,您只需要检查type == "object",然后删除不需要的成员.例如

Your problem is when type == "array" is true . will be an array so .userGroupAccesses won't work. What you want to do is focus on the case when . is an object. In your call to walk you only need to check for type == "object" and then remove the members you don't want. e.g.

walk(if type == "object" then del(.publicAccess, .userGroupAccesses) else . end)

在jqplay.org上在线试用

您还可以通过使用递归下降..来解决此问题,而无需walk 例如

You can also solve this without walk by using Recursive Descent .. e.g.

del(.. | .publicAccess?, .userGroupAccesses?)

在jqplay.org上在线试用

这篇关于用jq删除与键匹配的对象和数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆