如何仅使用jq将嵌套JSON转换为CSV

如何仅使用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 } }

我一直在关注json

{
    "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(",")

下面是一个使用tostreamgroupby

    [
        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
脚本相当复杂。想分享一下它是如何工作的吗?另外,您认为需求中缺少什么?