使用与键匹配的jq删除对象和数组

时间:2017-11-18 21:30:41

标签: arrays json jq

我有一个包含以下内容的JSON:

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

我想删除所有匹配publicAccessuserGroupAccesses的密钥(递归),以便我的JSON看起来像这样:

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

我已从source复制了jq的内置walk功能。

# 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[] - 我如何得到结果?

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

1 个答案:

答案 0 :(得分:8)

您的问题是type == "array"为真时.将是一个数组,因此.userGroupAccesses将无效。你想要做的是关注.是一个对象的情况。在致电walk时,您只需要检查type == "object",然后删除您不想要的成员。 e.g。

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

Try it online at jqplay.org

您也可以使用Recursive Descent ..例如

在没有walk的情况下解决此问题
del(.. | .publicAccess?, .userGroupAccesses?)

Try it online at jqplay.org

相关问题