【问题标题】:Convert json to csv / jq Cannot iterate over string将 json 转换为 csv / jq 不能迭代字符串
【发布时间】:2019-11-21 17:32:59
【问题描述】:
[
{
    "Description": "Copied for Destination xxx from Sourc 30c for Snapshot 1. Task created on X,52,87,14,76.",
    "Encrypted": false,
    "ID": "snap-074",
    "Progress": "100%",
    "Time": "2019-06-11T09:25:23.110Z",
    "Owner": "883065",
    "Status": "completed",
    "Volume": "vol1",
    "Size": 16
},
{
    "Description": "Copied for Destination yy from Source 31c for Snapshot 2. Task created on X,52,87,14,76.",
    "Encrypted": false,
    "ID": "snap-096",
    "Progress": "100%",
    "Time": "2019-06-11T10:18:01.410Z",
    "Owner": "1259",
    "Status": "completed",
    "Volume": "vol-2",
    "Size": 4
}

]

我有那个 json 文件,我正在尝试使用以下命令将其转换为 csv:

     jq -r '. | map(.Description[], .Encrypted, .ID, .Progress, .Time, .Owner, .Status, .Volume, .Size | join(",")) | join("\n")' snapshots1.json

但我遇到了错误:

jq: error (at snapshots1.json:24): Cannot iterate over string ("Copied for...)

我在jq: error: Cannot iterate over string 中查看了类似的帖子,但无法找出错误。任何帮助表示赞赏。

【问题讨论】:

    标签: json object export-to-csv jq


    【解决方案1】:

    我认为你是在正确的轨道上。这是我的做法:

    jq -r '.[] | map(..) | @csv' snapshot1.json > snapshot1.csv
    

    您的代码有几个小问题:

    1. .Descriptions[] - 描述没有数组,所以方括号不起作用 - 没有要打开的数组。
    2. 假设我们去掉方括号,您会看到代码的工作原理是将对象的内容放入数组中。但是,它将内容放入一个数组中 - 结果是您的 csv 将只有一行(我假设您希望每个对象位于不同的行中。)。这是因为 map 函数将所有内容放入一个数组中(请参阅文档:jq Manual) - 所以您必须先拆分打开数组。
    3. 带有点 (.) 的代码的第一部分不执行任何操作 - 它只是按原样返回整个 JSON。如果您想尝试一下,请尝试.[],然后从那里进行试验。

    编辑:拼写

    【讨论】:

    • 它不适用于 '.[] | ...' 出现错误:无法使用字符串“描述”索引字符串。我能够使用我分享的答案使其工作
    【解决方案2】:

    在此处使用.. 提取对象中的“值”存在风险:如果输入对象中键的顺序在对象之间不同怎么办?

    这里有一个通用过滤器,可以解决这个问题和其他问题。它还会发出一个合适的“标题”行:

    def object2array(stream):
      foreach stream as $x (null;
        if . == null then $x | [true, keys_unsorted] else .[0]=false end;
        (if .[0] then .[1] else empty end),
        .[1] as $keys | $x | [getpath( $keys[] | [.]) ] );
    

    示例

    def data: [{a:1,b:2}, {b:22,a:11,c:0}];
    
    object2array(data[])
    

    产生:

    ["a","b"]
    [1,2]
    [11,22]
    

    正好适合管道到@csv@tsv

    解决方案

    所以原始问题的解决方案基本上是:

    object2array(.[]) | @csv
    

    【讨论】:

      【解决方案3】:
      jq -r '(map(keys) | add | unique) as $cols | map(. as $row | $cols | map($row[.])) as $rows | $cols, $rows[] | @csv' snapshots1.json >> myfile.csv
      

      找到解释此代码的 post,它对我有用。

      【讨论】:

        猜你喜欢
        • 2021-09-03
        • 2016-03-24
        • 2019-04-07
        • 1970-01-01
        • 2022-01-01
        • 2015-06-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多