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

时间:2017-06-25 07:53:49

标签: json csv nested jq

我跟随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(keys)| add | unique)as $ cols | map(。作为$ row | $ cols | map($ row [。]))为$ rows | $ rows [] | @csv'

它给我一个错误。

我无法对父键进行硬编码,因为实际的json记录太多了。但是json的结构是相似的。我错过了什么?

2 个答案:

答案 0 :(得分:4)

有些要求不清楚,但以下解释了对问题的一种解释:

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

答案 1 :(得分:0)

以下是使用 tostream group_by

的解决方案
    [
        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"