【问题标题】:How to convert nested JSON to CSV using only jq如何仅使用 jq 将嵌套的 JSON 转换为 CSV
【发布时间】:2017-11-28 09:19:11
【问题描述】:

我已经关注 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

输出描述:将打印父母键,直到我到达叶子孩子。一旦我到达叶子孩子,打印它的值。

我尝试过关注,但未能成功,

猫我的.json | jq -r '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $行[] | @csv'

它给我一个错误。

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

【问题讨论】:

    标签: json csv nested jq


    【解决方案1】:

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

    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! jq 脚本相当复杂。愿意分享它是如何工作的吗?另外,您认为需求中缺少什么?
    【解决方案2】:

    这是一个使用 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"
    

    【讨论】:

      猜你喜欢
      • 2022-11-02
      • 2020-05-06
      • 2022-08-14
      • 1970-01-01
      • 2021-02-27
      • 1970-01-01
      • 2015-06-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多