使用 jq 从面向列的 JSON 中提取值并采用 CSV 格式

使用 jq 从面向列的 JSON 中提取值并采用 CSV 格式

我有以下 JSON 文件,其中数据存储为rank数组中枚举的列:

{
  "data": [
    {
      "displayName": "First Name",
      "rank": 1,
      "value": "VALUE"
    },
    {
      "displayName": "Last Name",
      "rank": 2,
      "value": "VALUE"
    },
    {
      "displayName": "Position",
      "rank": 3,
      "value": "VALUE"
    },
    {
      "displayName": "Company Name",
      "rank": 4,
      "value": "VALUE"
    },
    {
      "displayName": "Country",
      "rank": 5,
      "value": "VALUE"
    }
  ]
}

我想要一个这种格式的 CSV 文件,其中标题来自列的值displayName,列中的数据是单数value键的值:

First Name, Last Name, Position, Company Name, Country
VALUE, VALUE, VALUE, VALUE, VALUE

仅使用这可能吗jq?我没有任何编程技能。

答案1

jq 有一个过滤器 @csv,用于将数组转换为 CSV 字符串。此过滤器考虑了与 CSV 格式相关的大部分复杂性,从字段中嵌入的逗号开始。 (jq 1.5 有一个类似的过滤器 @tsv,用于生成制表符分隔值文件。)

当然,如果标题和值都保证没有逗号和双引号,那么可能不需要使用@csv过滤器。否则,使用它可能会更好。

例如,如果“公司名称”为“Smith, Smith and Smith”,并且其他值如下所示,则使用“-r”选项调用 jq 将生成有效的 CSV:

$ jq -r '.data | map(.displayName), map(.value) | @csv' so.json2csv.json
"First Name","Last Name","Position","Company Name","Country"
"John (""Johnnie"")","Doe","Director, Planning and Posterity","Smith, Smith and Smith","Transylvania"

答案2

我更喜欢将每条记录放在 CSV 中的一行中。

jq -r '.data | map([.displayName, .rank, .value] | join(", ")) | join("\n")'

给定问题中的数据,输出

First Name, 1, VALUE
Last Name, 2, VALUE
Position, 3, VALUE
Company Name, 4, VALUE
Country, 5, VALUE

答案3

仅给出这个文件,您可以执行以下操作:

<testfile jq -r '.data | map(.displayName), map(.value) | join(", ")'

操作.员从对象/散列中选择一个字段。因此,我们从 开始.data,它返回其中包含数据的数组。然后,我们对数组进行两次映射,首先选择 displayName,然后选择值,得到两个仅包含这些键的值的数组。对于每个数组,我们用“,”将元素连接起来形成两行。该-r参数告诉jq不要引用结果字符串。

如果您的实际文件较长(即包含多个人的条目),您可能需要更复杂的东西。

答案4

由于您标记了此文件python并假设文件名jsonx.json

import os, json
with open('x.json') as f:
    x  = json.load(f)
    print '{}{}{}'.format(', '.join(y['displayName'] for y in x['data']), os.linesep,
             ', '.join(y['value'] for y in x['data']))
First Name, Last Name, Position, Company Name, Country
VALUE, VALUE, VALUE, VALUE, VALUE

相关内容