我正在尝试设计一些关系表来保存各种 json 流的解析输出。数据流具有相当复杂的结构,为了便于表设计,我需要知道每个流的每一级嵌套键。我不知道如何使用 jq 从流中获取每个嵌套的键。下面是一个简化的代表性json流。
{
"startAt": 0,
"total": 5315,
"issues": [
{
"id": "44269",
"name": "someName",
"fields": {
"fixVersions": [
{
"id": "11401",
"releaseDate": "2016-09-30"
}
],
"status": {
"id": "10110",
"statusCategory": {
"id": 3,
"name": "Done"
}
}
}
},
{
"id": "44270",
"key": "LEAD-XXXX",
"fields": {
"assignee": {
"id": "10111",
"name": "Don"
},
"status": {
"id": "10110",
"statusCategory": {
"id": 2,
"name": "inProgress"
}
}
}
}
]
}
我期待以下输出。我很乐意有更好的方法来帮助我进行 table 设计。
startAt
total
issues: []
issues:id
issues:name
issues:key
issues:fields
issues:fields:fixVersions: []
issues:fields:fixVersions:id
issues:fields:fixVersions:releaseDate
issues:fields:status
issues:fields:status:id
issues:fields:status:statusCategory
issues:fields:status:statusCategory:id
issues:fields:status:statusCategory:name
issues:fields:assignee
issues:fields:assignee:id
issues:fields:assignee:name
如何使用 jq 获取上述流的嵌套键。非常感谢帮助。
最佳答案
I would be more than happy to have a better approach ...
如果我是你,我会从以下几点开始(也许结束):
[paths(scalars) | map(if type == "number" then 0 else . end)]
| unique
| .[]
在您的示例中,使用 -cr 命令行选项会产生:
["issues",0,"fields","assignee","id"]
["issues",0,"fields","assignee","name"]
["issues",0,"fields","fixVersions",0,"id"]
["issues",0,"fields","fixVersions",0,"releaseDate"]
["issues",0,"fields","status","id"]
["issues",0,"fields","status","statusCategory","id"]
["issues",0,"fields","status","statusCategory","name"]
["issues",0,"id"]
["issues",0,"key"]
["issues",0,"name"]
["startAt"]
["total"]
您可以更接近您所表示的您希望我将数字 0 映射到字符串的内容,但是您必须小心该字符串和键名之间的潜在冲突。为了显示:
[paths(scalars) | map(if type == "number" then "[]" else . end)]
| unique
| .[]
| join(":")
产生:
issues:[]:fields:assignee:id
issues:[]:fields:assignee:name
issues:[]:fields:fixVersions:[]:id
issues:[]:fields:fixVersions:[]:releaseDate
issues:[]:fields:status:id
issues:[]:fields:status:statusCategory:id
issues:[]:fields:status:statusCategory:name
issues:[]:id
issues:[]:key
issues:[]:name
startAt
total
请注意,这种方法产生的结果与基于模式推理的方法基本相同。这是一件好事。
使用 INDEX/2
使用
unique/0
如上所述有两个潜在的缺点:(1)输出的排序不反射(reflect)数据中的排序; (2) 效率(尽管在实践中这不太可能是一个真正的问题,除了具有大量叶路径的 JSON 文本)。无论如何,
INDEX/2
可以用来代替 unique
.如果您的 jq 没有 INDEX/2
,这里给出了它的定义。简而言之:
def INDEX(stream; idx_expr):
reduce stream as $row ({};
.[$row|idx_expr|
if type != "string" then tojson
else .
end] |= $row);
INDEX(paths(scalars)
| map(if type == "number" then "[]" else . end); .)
| .[]
| join(":")
产量:
startAt
total
issues:[]:id
issues:[]:name
issues:[]:fields:fixVersions:[]:id
issues:[]:fields:fixVersions:[]:releaseDate
issues:[]:fields:status:id
issues:[]:fields:status:statusCategory:id
issues:[]:fields:status:statusCategory:name
issues:[]:key
issues:[]:fields:assignee:id
issues:[]:fields:assignee:name
空数组的路径
如果您还希望报告空数组的路径,您可以(例如)简单地将“路径(标量)”更改为“(路径(标量),路径(数组))”。
关于json - 如何使用 jq 获取 json 流的嵌套键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46973467/