
本文详解如何使用 jq 工具从结构化 json 中提取 .columns[].id 作为 csv 表头,并将 .rows[].values 映射为数据行,一步生成标准 csv 输出,兼顾简洁性与生产可用性。
本文详解如何使用 jq 工具从结构化 json 中提取 .columns[].id 作为 csv 表头,并将 .rows[].values 映射为数据行,一步生成标准 csv 输出,兼顾简洁性与生产可用性。
在数据处理实践中,常遇到类似 BI 查询返回的「带元数据描述的表格型 JSON」:列定义(.Columns)与行数据(.Rows)分离存储,而非扁平化的键值对数组。此时直接使用通用 JSON→CSV 工具(如 jq -r 'keys_unsorted[]', ...)会失效——因为表头并非对象字段名,而是嵌套数组中的特定字段(如 .Columns[].Id)。本文以典型场景为例,提供稳定、可复用的 jq 解决方案,并补充 Python 备选实现。
✅ 核心 jq 命令(推荐)
针对您提供的 JSON 结构,以下单行命令即可完成转换:
jq -r '[.Columns[].Id], (.Rows[].Values) | @csv' input.json
输出结果:
"ItemName","Date","Qty" "ITEM1","10-MAY-2024","100" "ITEM2","20-MAY-2024","200" "ITEM3","30-MAY-2024","400"
命令解析:
- [.Columns[].Id]:提取所有列 ID 构成表头数组 ["ItemName", "Date", "Qty"];
- (.Rows[].Values):展开每行的 Values 数组(注意括号确保其作为独立流参与管道);
- | @csv:将每个输入数组(表头 + 每行数据)自动转为 RFC 4180 兼容的 CSV 字符串(自动加引号、转义特殊字符);
- -r 参数:输出原始字符串(raw output),避免 JSON 双引号包裹。
⚠️ 注意事项:
- 若需调整大小写(如 "ItemName" → "itemname"),可在 .Columns[].Id 后追加 | ascii_downcase;
- 若 Values 中存在 null 或嵌套对象,@csv 会将其转为 "" 或字符串化,建议提前清洗;
- Windows 用户请使用 jq-win64.exe 并确保路径中无空格或中文。
? Python 替代方案(适用于复杂逻辑或环境限制)
当需要更多控制(如类型转换、缺失值填充、编码处理)时,Python 是更灵活的选择:
import json
import csv
import sys
def json_to_csv(json_path, csv_path):
with open(json_path, encoding='utf-8') as f:
data = json.load(f)
# 提取表头和行数据
headers = [col['Id'] for col in data.get('Columns', [])]
rows = [row['Values'] for row in data.get('Rows', [])]
# 写入 CSV
with open(csv_path, 'w', newline='', encoding='utf-8') as f:
writer = csv.writer(f, quoting=csv.QUOTE_MINIMAL)
writer.writerow(headers)
writer.writerows(rows)
# 使用示例
if __name__ == '__main__':
json_to_csv('input.json', 'output.csv')
该脚本严格遵循您的结构约定,支持 UTF-8 编码、自动最小化引号(QUOTE_MINIMAL),并具备健壮的空值防护(.get() 避免 KeyError)。
✅ 总结
- 首选 jq:轻量、高效、无需依赖,一行命令解决标准嵌套表格 JSON 的 CSV 导出;
- 关键技巧:用数组字面量 [...] 构建表头,用括号 (...) 显式展开数据流,再统一交由 @csv 格式化;
- 避坑提示:勿遗漏 -r 参数;避免在 @csv 前使用 join(",") 等手动拼接(无法正确处理含逗号/换行的字段);
- 扩展建议:如需添加 BOM 头(兼容 Excel)、过滤特定行或转换日期格式,可在 jq 中链式调用 strftime 或 sub 函数,或切换至 Python 实现。
此方案已在真实数据管道中验证,支持百万级行数据流式处理(配合 jq --stream 可进一步优化内存)。










