【问题标题】:How do I write a jq query to convert a JSON file to CSV?如何编写 jq 查询以将 JSON 文件转换为 CSV?
【发布时间】:2022-01-20 14:15:49
【问题描述】:

JSON 文件如下所示:

{
  "name": "My Collection",
  "description": "This is a great collection.",
  "date": 1639717379161,
  "attributes": [
    {
      "trait_type": "Background",
      "value": "Sand"
    },
    {
      "trait_type": "Skin",
      "value": "Dark Brown"
    },
    {
      "trait_type": "Mouth",
      "value": "Smile Basic"
    },
    {
      "trait_type": "Eyes",
      "value": "Confused"
    }
  ]  
}

我发现 a shell script 使用 jq 并且有这个代码:

i=1
for eachFile in *.json; do
    cat $i.json | jq -r '.[] | {column1: .name, column2: .description} | [.[] | tostring] | @csv' > extract-$i.csv
    echo "converted $i of many json files..."
    ((i=i+1))
done

但它的输出是:

jq: error (at <stdin>:34): Cannot index string with string "name"
converted 1 of many json files...

对我如何使这项工作有任何建议?谢谢!

【问题讨论】:

  • 您根本没有使 jq 过滤器适应您的实际 JSON。
  • @chepner 我将其更新为使用namedescription 字段。你可以说得更详细点吗?我不明白jq
  • 您需要编写一个jq 命令,将给定的 JSON 文件转换为 CSV。问题不是你的 shell 脚本,而是 jq 的调用。
  • @AndyLester 没错,那么我该如何编写这个命令呢?这就是为什么我要问 Stack Overflow ;)
  • 我们不知道您想要什么样的转换,但那里有很多很好的 jq 教程。

标签: json csv jq


【解决方案1】:

快速jq课程
===========

jq 过滤器的应用如下:
jq -r '.name_of_json_field_0 &lt;optional filter&gt;, .name_of_json_field_1 &lt;optional filter&gt;'
等等等等。单点是最简单的过滤器;它使数据字段保持不变。

jq -r '.name_of_field .'

您也可以保持过滤器字段不变以获得相同的效果。 在你的情况下: jq -r '.name, .description' 将提取这两个字段的值。

.[] 将展开一个数组以将下一个管道过滤器应用于每个展开的值。示例:
jq -r '.attributes | .[]
提取所有 trait_types 对象。

您有时可能希望通过将过滤器括在括号中来重新打包数组中的对象:
jq -r '[.name, .description, .date]

您有时可能希望通过将过滤器括在花括号中来重新打包对象中的数据:
`jq -r '{new_field_name: .name, super_new_field_name: .description}'

玩弄这些,我能够得到

jq -r '[.name, .description, .date, (.attributes | [.[] | .trait_type] | @csv | gsub(",";";") | gsub("\"";"")), (.attributes | [.[] | .value] | .[]] | @csv | gsub(",";";") | gsub("\"";""))] | @csv'

给我们:
"My Collection","This is a great collection.",1639717379161,"Background;Skin;Mouth;Eyes","Sand;Dark Brown;Smile Basic;Confused"

名称、描述和日期保持原样,所以让我们一步一步分解奇怪的部分。

.attributes | [.[] | .trait_type]
.[] 提取属性数组的每个元素并将其结果通过管道传送到下一个过滤器,该过滤器表示只需提取trait_type,然后将它们重新打包到一个数组中。

.attributes | [.[] | .trait_type] | @csv
将数组转换为 csv 可解析格式。

(.attributes | [.[] | .trait_type] | @csv | gsub(",";";") | gsub("\"";""))
显然,Parens 将其与其他评估区分开来。 第一个 gsub 在这里用分号替换逗号,因此它们不会被解释为单独的字段,第二个删除所有额外的双引号。

【讨论】:

    猜你喜欢
    • 2018-08-20
    • 1970-01-01
    • 1970-01-01
    • 2022-01-01
    • 2015-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多