使用jq将JSON转CSV:解决valuePerDay键值行输出与排序问题
使用jq将带动态键的JSON转成有序CSV
核心需求
- 每个JSON对象对应CSV的一行,
valuePerDay的键值对展开为列 - 对
valuePerDay的键排序,保证所有行的列位置完全一致
示例输入JSON
{ "arr": [ { "id": "1", "name": "A", "valuePerDay": { "2024-05-01": 10, "2024-05-03": 20, "2024-05-02": 15 } }, { "id": "2", "name": "B", "valuePerDay": { "2024-05-01": 5, "2024-05-02": 8, "2024-05-03": 12 } } ] }
错误代码及问题
之前的代码会拆分valuePerDay的键值对为多行,导致重复输出:
.arr[] | [.id, .name, (.valuePerDay | to_entries[] | .value)] | @csv
错误输出:
"1","A",10 "1","A",20 "1","A",15 "2","B",5 "2","B",8 "2","B",12
正确解决方案
通过变量存储排序后的键,统一表头和每行的列顺序:
# 提取并排序valuePerDay的键(假设所有对象键一致,取第一个对象的键即可) ( .arr[0].valuePerDay | keys | sort ) as $sortedKeys # 生成表头:固定列 + 排序后的动态键 | ( ["id", "name"] + $sortedKeys ), # 遍历每个对象,按排序后的键提取对应值 ( .arr[] | [.id, .name] + ( $sortedKeys | map( .valuePerDay[.] ) ) ) # 转换为CSV格式 | @csv
正确输出
"id","name","2024-05-01","2024-05-02","2024-05-03" "1","A",10,15,20 "2","B",5,8,12
关键说明
- 排序键:用
keys | sort对动态键排序,确保所有行的列顺序统一 - 避免重复:不再拆分
valuePerDay为多行,而是将所有值按顺序放入同一数组,对应CSV的一行 - 兼容差异场景:如果实际JSON中
valuePerDay的键不完全一致,可改为先收集所有唯一键再排序:( .arr[] | .valuePerDay | keys ) | unique | sort
内容的提问来源于stack exchange,提问作者Sébastien BOURGEOIS
相关产品推荐
相关产品推荐

