如何用yq拼接字符串数组,实现JSON到合规CSV的转换?
解决嵌套JSON转CSV的yq实现方案
假设你的JSON输入结构类似这样(根节点为数组,每个条目包含id、name和labels数组):
[ { "id": 1, "name": "Item A", "labels": [{"name": "tag1"}, {"name": "tag2"}] }, { "id": 2, "name": "Item B", "labels": [{"name": "tag3"}] } ]
核心问题原因
你之前的命令会把labels.name展开为多列,是因为直接提取了数组中的每个name值,没有将它们合并为单个字段,导致CSV列数不统一,格式失效。
正确实现命令(基于mikefarah/yq v4.x)
以下两种方案都能满足需求:提取id、name,将labels的name用分号合并并包裹引号,且不会拆分多列。
方案1:手动构造CSV行(强制给labels列加引号)
适合需要强制包裹引号的场景,不管内容是否包含特殊字符:
yq -r ' # 输出表头 "id,name,labels" # 遍历每个条目,拼接行内容 , (.[] | "\(.id),\(.name),\"\(.labels | map(.name) | join(";"))\"") ' input.json
输出结果:
id,name,labels 1,Item A,"tag1;tag2" 2,Item B,"tag3"
方案2:使用@csv自动格式化(仅当内容含特殊字符时加引号)
如果允许只有当labels内容包含逗号/引号时才加引号,可使用@csv内置过滤器,更符合CSV规范:
yq -r ' # 定义表头 ["id", "name", "labels"] as $headers # 组合表头和所有行数据 | ($headers, (map([.id, .name, (.labels | map(.name) | join(";"))]))) # 转CSV格式 | @csv ' input.json
输出结果(当labels无特殊字符时不会加引号,有则自动添加):
id,name,labels 1,Item A,tag1;tag2 2,Item B,tag3
适配不同JSON结构
如果你的JSON根节点不是数组,而是包含数组的对象(比如{"data": [...]}),只需将命令中的.[]替换为.data[]即可。
内容的提问来源于stack exchange,提问作者codug
相关产品推荐
相关产品推荐

