我正在尝试使用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"
]
},
...
答案 0 :(得分:0)
我认为您想要这样的东西:
# 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
的回显输入作为流过滤器inputs
(而不是.
)作为流过滤器,以便我们一次处理全部输入,以便将结果包装在外括号中。
-n
在这里很重要,因为它指示jq
不能隐式使用管道输入。.id as $id
我们将父ID保存到$id
变量中以供将来参考| policyItems[]
我们正在遍历policyItems数组,这似乎是您希望对结果进行分组的依据| {"id": $id, ...
在这里,我们开始构建结果,并返回到我们保存的$id
。"access_type": (reduce .accesses[].type as $item ([]; . + [$item])), ...
在这里,我们使用reduce
过滤器将访问类型组合到单个数组中"users_groups": (.users + .groups)}
,我们最终将"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"
]
}
]