Json JQ获取嵌套数组的错误输出

Json JQ获取嵌套数组的错误输出,json,jq,Json,Jq,我正在尝试使用JQ将json文件转换为csv文件。我已经设法对文件执行了此操作,但在测试期间,我发现输出并不像预期的那样。我花了好几个小时试图修好它,但似乎到不了那里,请你帮忙 理想情况下,我也想将用户和组合并为一个,但我可以不这样做 这是我的json文件的精简版本 [ { "id": 319, "policyItems": [ { "accesses": [ { "type": "consume",

我正在尝试使用JQ将json文件转换为csv文件。我已经设法对文件执行了此操作,但在测试期间,我发现输出并不像预期的那样。我花了好几个小时试图修好它,但似乎到不了那里,请你帮忙

理想情况下,我也想将用户和组合并为一个,但我可以不这样做

这是我的json文件的精简版本

[
  {
    "id": 319,
    "policyItems": [
      {
        "accesses": [
          {
            "type": "consume",
            "isAllowed": true
          },
          {
            "type": "create",
            "isAllowed": true
          }
        ],
        "users": [
          "foo"
        ],
        "groups": []
      },
      {
        "accesses": [
          {
            "type": "publish",
            "isAllowed": true
          },
          {
            "type": "create",
            "isAllowed": true
          }
        ],
        "users": [],
        "groups": [
          "bar"
        ]
      }
    ]
  },
  {
    "id": 320,
    "policyItems": [
      {
        "accesses": [
          {
            "type": "publish",
            "isAllowed": true
          },
          {
            "type": "create",
            "isAllowed": true
          }
        ],
        "users": [
          "foo"
        ],
        "groups": []
      },
      {
        "accesses": [
          {
            "type": "consume",
            "isAllowed": true
          },
          {
            "type": "create",
            "isAllowed": true
          }
        ],
        "users": [],
        "groups": [
          "bar"
        ]
      }
    ]
    }
]
我尝试了这个JQ代码的各种版本,但是对于id=319,user=foo应该有访问消费和创建的权限,而group=bar应该有访问发布和创建的权限。但我总是以foo和bar都可以访问消费、发布和创建(或其他错误)而告终

我试过:

cat file.json | jq -r '[.[] | select(has("policyItems")) |{"id", "users":(.policyItems[] | .users), "groups":(.policyItems[] | .groups), "access_type":([.policyItems[].accesses[] | .type])} ] '
输出:

      [
      {
        "id": 319,
        "users": [
          "foo"
        ],
        "groups": [],
        "access_type": [
          "consume",
          "create",
          "publish",
          "create"
        ]
      },
      {
        "id": 319,
        "users": [
          "foo"
        ],
        "groups": [
          "bar"
        ],
        "access_type": [
          "consume",
          "create",
          "publish",
          "create"
        ]
      },
      {
        "id": 319,
        "users": [],
        "groups": [],
        "access_type": [
          "consume",
          "create",
          "publish",
          "create"
        ]
      },
      {
        "id": 319,
        "users": [],
        "groups": [
          "bar"
        ],
        "access_type": [
          "consume",
          "create",
          "publish",
          "create"
        ]
      },
      {
        "id": 320,
        "users": [
          "foo"
        ],
        "groups": [],
        "access_type": [
          "publish",
          "create",
          "consume",
          "create"
        ]
      },
      {
        "id": 320,
        "users": [
          "foo"
        ],
        "groups": [
          "bar"
        ],
        "access_type": [
          "publish",
          "create",
          "consume",
          "create"
        ]
      },
      {
        "id": 320,
        "users": [],
        "groups": [],
        "access_type": [
          "publish",
          "create",
          "consume",
          "create"
        ]
      },
      {
        "id": 320,
        "users": [],
        "groups": [
          "bar"
        ],
        "access_type": [
          "publish",
          "create",
          "consume",
          "create"
        ]
      }
      ]
我还尝试:

cat file.json | jq  ' map({id, "access_type":([.policyItems[].accesses[] | .type])[], "users":(.policyItems[] | .users)[], "groups":(.policyItems[] | .groups)}) '
它提供输出:

    [
{
    "id": 319,
    "access_type": "consume",
    "users": "foo",
    "groups": []
  },
  {
    "id": 319,
    "access_type": "consume",
    "users": "foo",
    "groups": [
      "public"
    ]
  },
  {
    "id": 319,
    "access_type": "create",
    "users": "foo",
    "groups": []
  },
  {
    "id": 319,
    "access_type": "create",
    "users": "foo",
    "groups": [
      "public"
    ]
  },
  {
    "id": 319,
    "access_type": "publish",
    "users": "foo",
    "groups": []
  },
  {
    "id": 319,
    "access_type": "publish",
    "users": "foo",
    "groups": [
      "public"
    ]
  },
  {
    "id": 319,
    "access_type": "create",
    "users": "foo",
    "groups": []
  },
  {
    "id": 319,
    "access_type": "create",
    "users": "foo",
    "groups": [
      "public"
    ]
  },
  {
    "id": 320,
    "access_type": "publish",
    "users": "foo",
    "groups": []
  },
  {
    "id": 320,
    "access_type": "publish",
    "users": "foo",
    "groups": [
      "public"
    ]
  },
  {
    "id": 320,
    "access_type": "create",
    "users": "foo",
    "groups": []
  },
  {
    "id": 320,
    "access_type": "create",
    "users": "foo",
    "groups": [
      "public"
    ]
  },
  {
    "id": 320,
    "access_type": "consume",
    "users": "foo",
    "groups": []
  },
  {
    "id": 320,
    "access_type": "consume",
    "users": "foo",
    "groups": [
      "public"
    ]
  },
  {
    "id": 320,
    "access_type": "create",
    "users": "foo",
    "groups": []
  },
  {
    "id": 320,
    "access_type": "create",
    "users": "foo",
    "groups": [
      "public"
    ]
    }
    ]
提前谢谢

编辑: 我期望的输出是这样的,用户和组被组合在一起,并正确地显示正确的访问

  [
  {
    "id": 319,
    "users_groups": [
      "foo",
      "bar"
    ],
    "access_type": [
      "create"
    ]
  },
  {
    "id": 319,
    "users_groups": [
      "foo"
    ],
    "access_type": [
      "consume"
    ]
  },
  {
    "id": 319,
    "users_groups": ["bar"],
    "access_type": [
      "publish"
    ]
  },
  ...

我想你想要这样的东西:

# Print out your top example input
echo '{"id":319,"policyItems":[{"accesses":[{"type":"consume","isAllowed":true},{"type":"create","isAllowed":true}],"users":["foo"],"groups":[]},{"accesses":[{"type":"publish","isAllowed":true},{"type":"create","isAllowed":true}],"users":[],"groups":["bar"]}]}
{"id":320,"policyItems":[{"accesses":[{"type":"publish","isAllowed":true},{"type":"create","isAllowed":true}],"users":["foo"],"groups":[]},{"accesses":[{"type":"consume","isAllowed":true},{"type":"create","isAllowed":true}],"users":[],"groups":["bar"]}]}' \
| jq -n '[inputs | .id as $id | .policyItems[] | {"id": $id, "access_type": (reduce .accesses[].type as $item ([]; . + [$item])), "users_groups": (.users + .groups)}]'
下面是正在发生的事情:

  • echo'{“id”:…
    我们正在回显您的输入
  • |jq
    将管道连接到
    jq
  • jq-n'[inputs |…]
    我们接受
    jq
    中的回显输入作为流式过滤器
    输入(而不是
    ),以便我们一次处理整个输入,以便将结果包装在外括号中。
    • -n
      在这里很重要,因为它指示
      jq
      不要隐式使用管道输入
  • .id为$id
    我们将父id保存到
    $id
    变量中以供将来参考
  • | policyItems[]
    我们正在迭代policyItems数组,您似乎希望根据该数组对结果进行分组
  • {“id”:$id,
    这里我们开始构建结果,并返回到我们保存的
    $id
  • “访问类型”:(reduce.accesss[].type为$item([];.+[$item]),…
    这里我们使用
    reduce
    过滤器将访问类型组合到单个数组中
  • “用户组”:(.users+.groups)}
    我们最终将
    “用户”
    “组”
    数组合并为一个数组
所有这些都允许我们返回如下输出:

[
  {
    "id": 319,
    "access_type": [
      "consume",
      "create"
    ],
    "users_groups": [
      "foo"
    ]
  },
  {
    "id": 319,
    "access_type": [
      "publish",
      "create"
    ],
    "users_groups": [
      "bar"
    ]
  },
  {
    "id": 320,
    "access_type": [
      "publish",
      "create"
    ],
    "users_groups": [
      "foo"
    ]
  },
  {
    "id": 320,
    "access_type": [
      "consume",
      "create"
    ],
    "users_groups": [
      "bar"
    ]
  }
]

您的预期输出是什么?@hek2mgl-我已将预期输出添加到原始问题中。提前感谢。