如何仅使用jq将嵌套JSON转换为CSV
我一直在关注json如何仅使用jq将嵌套JSON转换为CSV,json,csv,nested,jq,Json,Csv,Nested,Jq,我一直在关注json { "A": { "C": { "D": "T1", "E": 1 }, "F": { "D": "T2", "E": 2 } }, "B": { "C": { "D": "T3", "E": 3 } }
{
"A": {
"C": {
"D": "T1",
"E": 1
},
"F": {
"D": "T2",
"E": 2
}
},
"B": {
"C": {
"D": "T3",
"E": 3
}
}
}
我想将其转换为csv,如下所示
A,C,T1,1
A,F,T2,2
B,C,T3,3
输出说明:将打印父密钥,直到我到达叶子级。一旦我到达叶子树,打印它的值
我试过跟随,但没有成功
cat my.json | jq-r'(map(key)| add | unique)作为$cols | map(.as$row |$cols | map($row[.]))作为$rows |$rows[]@csv
这给了我一个错误
我不能硬编码父键,因为实际的json有太多记录。但是json的结构是相似的。我遗漏了什么?一些要求不清楚,但以下解决了对问题的一种解释:
paths as $path
| {path: $path, value: getpath($path)}
| select(.value|type == "object" )
| select( [.value[]][0] | type != "object")
| .path + ([.value[]])
| @csv
(此程序可以优化,但此处的演示旨在明确各个步骤。)
调用:
jq -r -f leaves-to-csv.jq input.json
输出:
"A","C","T1",1
"A","F","T2",2
"B","C","T3",3
无引号字符串
为了避免字符串周围的引号,您可以将上面管道的最后一个组件替换为:
join(",")
下面是一个使用tostream和groupby
[
tostream
| select(length == 2) # e.g. [["A","C","D"],"T1"]
| .[0][:-1] + [.[1]] # ["A","C","T1"]
]
| group_by(.[:-1]) # [[["A","C","T1"],["A","C",1]],...
| .[] # [["A","C","T1"],["A","C",1]]
| .[0][0:2] + map(.[-1]|tostring) # ["A","C","T1","1"]
| join(",") # "A,C,T1,1"
它的工作完美无瑕,+1!
jq
脚本相当复杂。想分享一下它是如何工作的吗?另外,您认为需求中缺少什么?