【问题标题】:Parsing JSON file and converting into csv file using jq使用 jq 解析 JSON 文件并转换为 csv 文件
【发布时间】:2019-03-16 06:36:35
【问题描述】:

根据该部分,我正在尝试解析我的数据并将它们转换为多个 csv 文件。

示例 JSON

{
    "content": [
    {
        "Title": "abc",
        "brand": "xyz",
        "size": "5 g",
        "date": "2019-01-01",
        "details": {
            "Temperature": [
            {
                "value": "90",
                "chracterstics":"Normal"
            },
            {
                "value":"100",
                "chracterstics":"high"
            },

            {
                "value":"80",
                "chracterstics":"low"
            }
            ],

            "certifications": [
            {
                "value": "based",
                "chracterstics":"pass"
            },

            {
                "value": "50",
                "chracterstics":"failed"
            }
            ]
        },

         "formats": {
            "city": "NYC",
            "id": "007",
            "manufacture":""
            },
        "innerDetails": [
        {
            "contains": "abc",
            "panel":"xyz",
            "values":[
                {
                    "name":"abc",
                    "value":"10"
                },
                {
                    "name":"xyz",
                    "value":"20"
                }
                ]
            }
        ]
}
]
}

我正在尝试将内容数据放入一个 csv 文件中,将温度数据放入第二个 csv 文件中,将认证放入第三个文件中,将格式和内部详细信息数据放入另一个单独的文件中.

我尝试了以下方法,但出现“Cannot index array with string "brand"”错误。

jq -r '.[]|[.Title,.brand,.size,.date]|@csv' $jsonfile > sample.csv.

我尝试与其他部分在同一行,但得到相同的错误。

我该如何解决这个问题?

【问题讨论】:

  • JSON 不完全有效。将其粘贴到jsonlint.com 并查看错误
  • 我可以使用 jq -r '.content[]|[.Title,.brand,.size,.date]|@csv' $jsonfile > sample.csv 得到结果,但是我想知道有没有办法根据标题获取详细信息。因为,我有非常大的 json 文件,该文件有点类似于示例文件。例如使用内容标题的内容详细信息,使用innerDetails标题的innerDetails,使用格式标题的格式详细信息。
  • 要解析这个json,需要将“content”放在引号中,并且需要在这个sn-p的末尾加上“}] }”。

标签: shell jq


【解决方案1】:

为简单起见,最好在单独的 jq 调用中处理每组数据。 考虑到 jq 的每次调用都非常快,这在这里似乎是合理的,而且您似乎只需要少量这样的调用。

温度和认证数据在 JSON 输入中是统一的,因此可以在循环中处理,例如:

for field in Temperature certifications ; do
    echo $field ::
    jq --arg field "$field" -r '
      .content[].details | .[$field][]
      | [.value, .characteristics] | @csv' input.json > output.$field.csv
done    

(这当然假设 JSON 是有效的,并且“certifications”的拼写正确。)

添加“内容”特定的列

for field in Temperature certifications ; do
    echo $field ::
    jq --arg field "$field" -r '.content[]
      | [.Title, .brand] as $columns
      | .details | .[$field][]
      | ($columns + [.value, .characteristics]) | @csv
    ' so-multiple-csv-files.json > tmp.output.$field.csv
done    

【讨论】:

  • 我可以通过上面得到结果,但是是否可以将“标题”和“品牌”作为温度和认证相关文件的前两列?我试图将 [.Title, .brand, .value, .characteristics] 放在上面的代码中,但是这两列都为空白。
  • 感谢@peak 的支持。现在一切正常。
【解决方案2】:

使用地图:

$jq -r '.[] | map(.Title), map(.brand), map(.size), map(.date) | @csv' yourfile.json > sample.csv

【讨论】:

  • 感谢您的输入,但我想要一些通用循环结构用于详细信息字段。因为它包含大量的数组,如温度和证书,它们的值是“值”和“特征”,我想把温度、证书等放在它们各自的 csv 文件中。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-18
  • 2018-08-20
  • 1970-01-01
  • 2021-08-18
  • 2013-07-23
  • 1970-01-01
相关资源
最近更新 更多