想象一下,我有一个像这个JSON文件的类别树:
[
{
"id": "1",
"text": "engine",
"children": [
{
"id": "2",
"text": "exhaust",
"children": []
},
{
"id": "3",
"text": "cooling",
"children": [
{
"id": "4",
"text": "cooling fan",
"children": []
},
{
"id": "5",
"text": "water pump",
"children": []
}
]
}
]
},
{
"id": "6",
"text": "frame",
"children": [
{
"id": "7",
"text": "wheels",
"children": []
},
{
"id": "8",
"text": "brakes",
"children": [
{
"id": "9",
"text": "brake calipers",
"children": []
}
]
},
{
"id": "10",
"text": "cables",
"children": []
}
]
}
]
如何将其转换为此平台?
id parent_id text
1 NULL engine
2 1 exhaust
3 1 cooling
4 3 cooling fan
5 3 water pump
6 NULL frame
7 6 wheels
8 6 brakes
9 8 brake calipers
10 6 cables
我发现了类似的问题和反向问题(从表格到JSON)但我无法用jq及其@tsv过滤器来解决这个问题。另外我注意到答案中经常引用“flatten”过滤器(虽然它看起来是我需要的确切工具),但可能是因为它最近在jq的最新版本中被引入。
答案 0 :(得分:1)
这里的关键是定义一个递归函数,如下所示:
def children($parent_id):
.id as $id
| [$id, $parent_id, .text],
(.children[] | children($id)) ;
使用您的数据,过滤器:
.[]
| children("NULL")
| @tsv
生成如下所示的制表符分隔值。现在可以轻松添加标题,如果需要,可以转换为固定宽度格式等。
1 NULL engine
2 1 exhaust
3 1 cooling
4 3 cooling fan
5 3 water pump
6 NULL frame
7 6 wheels
8 6 brakes
9 8 brake calipers
10 6 cables
答案 1 :(得分:1)
这是另一个使用jq recurse内置的解决方案:
["id","parent_id","text"]
, (
.[]
| recurse(.id as $p| .children[] | .parent=$p )
| [.id, .parent, .text]
)
| @tsv
示例运行(假定filter.jq
中的过滤器和data.json
中的样本数据)
$ jq -Mr -f filter.jq data.json
id parent_id text
1 engine
2 1 exhaust
3 1 cooling
4 3 cooling fan
5 3 water pump
6 frame
7 6 wheels
8 6 brakes
9 8 brake calipers
10 6 cables
答案 2 :(得分:0)
这是一个使用递归函数的解决方案:
def details($parent):
[.id, $parent, .text], # details for current node
(.id as $p | .children[] | details($p)) # details for children
;
["id","parent_id","text"] # header
, (.[] | details(null)) # details
| @tsv # convert to tsv
示例运行(假定filter.jq
中的过滤器和data.json
中的样本数据)
$ jq -Mr -f filter.jq data.json
id parent_id text
1 engine
2 1 exhaust
3 1 cooling
4 3 cooling fan
5 3 water pump
6 frame
7 6 wheels
8 6 brakes
9 8 brake calipers
10 6 cables