简体   繁体   English

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

[英]How to convert nested JSON to CSV using only jq

I've following json, 我一直在追踪json,

{
    "A": {
        "C": {
            "D": "T1",
            "E": 1
        },
        "F": {
            "D": "T2",
            "E": 2
        }
    },
    "B": {
        "C": {
            "D": "T3",
            "E": 3
        }
    }
}

I want to convert it into csv as follows, 我想如下将其转换为csv,

A,C,T1,1
A,F,T2,2
B,C,T3,3

Description of output: The parents keys will be printed until, I've reached the leaf child. 输出说明:父母的钥匙将被打印,直到我到达叶子的孩子为止。 Once I reached leaf child, print its value. 当我到达叶子后,打印其值。

I've tried following and couldn't succeed, 我已经尝试追踪但无法成功,

cat my.json | 猫my.json | jq -r '(map(keys) | add | unique) as $cols | jq -r'(map(keys)| add | unique)为$ cols | map(. as $row | $cols | map($row[.])) as $rows | map(。as $ row | $ cols | map($ row [。]))as $ rows | $rows[] | $ rows [] | @csv' @csv”

and it throwing me an error. 这让我犯了一个错误。

I can't hardcode the parent keys, as the actual json has too many records. 我无法对父键进行硬编码,因为实际的json有太多记录。 But the structure of the json is similar. 但是json的结构是相似的。 What am I missing? 我想念什么?

Some of the requirements are unclear, but the following solves one interpretation of the problem: 某些要求尚不清楚,但是以下解决了该问题的一种解释:

paths as $path
| {path: $path, value: getpath($path)}
| select(.value|type == "object" )
| select( [.value[]][0] | type != "object")
| .path + ([.value[]])
| @csv

(This program could be optimized but the presentation here is intended to make the separate steps clear.) (可以优化该程序,但是此处的演示旨在使各个步骤变得清晰。)

Invocation: 调用:

jq -r -f leaves-to-csv.jq input.json

Output: 输出:

"A","C","T1",1
"A","F","T2",2
"B","C","T3",3

Unquoted strings 未引用的字符串

To avoid the quotation marks around strings, you could replace the last component of the pipeline above with: 为了避免在字符串两边加上引号,可以将上面管道的最后一个组件替换为:

join(",")

Here is a solution using tostream and group_by 这是使用tostreamgroup_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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM