使用 jq 在 CSV 中提取值和格式

Ker*_*rim 74 bash python csv json jq

我有以下 JSON 文件:

{
"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"
    },
]
}
Run Code Online (Sandbox Code Playgroud)

我想要一个这种格式的 CSV 文件:

First Name, Last Name, Position, Company Name, Country
VALUE, VALUE, VALUE, VALUE, VALUE, VALUE
Run Code Online (Sandbox Code Playgroud)

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

pea*_*eak 70

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

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

例如,如果“公司名称”是“史密斯、史密斯和史密斯”,并且其他值如下所示,则使用“-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"
Run Code Online (Sandbox Code Playgroud)

  • 您的示例将把所有显示名称放在第一行,将所有值放在第二行,而不是每条记录一行。 (10认同)
  • 我能够'jq somestuff | 地图(.) | @csv',非常方便!谢谢 (6认同)

小智 44

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

jq '.data | map([.displayName, .rank, .value] | join(", ")) | join("\n")'
Run Code Online (Sandbox Code Playgroud)

  • @Cos,我发现需要括号。`(.value|tostring)` (5认同)
  • 另外,使用`jq -r` 去除引号 (5认同)
  • @Cos 在上面的例子中类似于 `.value|tostring` 而不是 `.value` (3认同)
  • 如果 .value 是一个数字怎么办?我收到错误“无法添加字符串和数字” (2认同)
  • @Kusalananda 确实如此,但由于问题标题广泛,许多人正在访问此页面以查找此答案的效果。 (2认同)
  • @Kusalananda 问题内容具体而精彩,但*标题*很宽泛。这个答案获得了第二高的支持,因为人们正在寻找这个特定的解决方案并由于标题而到达这里。 (2认同)

Ste*_*n D 33

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

<testfile jq -r '.data | map(.displayName), map(.value) | join(", ")'
Run Code Online (Sandbox Code Playgroud)

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

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


gle*_*man 12

我发现jq很难回过头来。这是一些红宝石:

ruby -rjson -rcsv -e '
  data = JSON.parse(File.read "file.json")
  data["data"].collect {|item| [item["displayName"], item["value"]]}
              .transpose
              .each {|row| puts row.to_csv}
'
Run Code Online (Sandbox Code Playgroud)
First Name,Last Name,Position,Company Name,Country
VALUE,VALUE,VALUE,VALUE,VALUE
Run Code Online (Sandbox Code Playgroud)

ruby JSON 解析器对右括号前的尾随逗号发出警告。