JSON数据转置透视工具推荐:70万文件1小时批量处理需求
批量JSON数据结构化处理方案
需求回顾
需在1小时内完成70万个JSON文件的结构化转换,将原始JSON中按ID分散的键值对分组,转换为指定格式的结构化表格。
原始JSON示例
{ "Report": [ { "IGD.LD.1.H.H.*.Active.1": "1", "IGD.LD.1.H.H.*.Active.2": "0", "IGD.LD.1.H.H.*.Active.3": "1", "IGD.LD.1.H.H.*.Active.4": "0", "IGD.LD.1.H.H.*.HName.1": "AAA", "IGD.LD.1.H.H.*.HName.2": "BBB", "IGD.LD.1.H.H.*.HName.3": "CCC", "IGD.LD.1.H.H.*.HName.4": "DDDD", "IGD.LD.1.H.H.*.X_HW_Stats.BR.1": "123", "IGD.LD.1.H.H.*.X_HW_Stats.BR.2": "456", "IGD.LD.1.H.H.*.X_HW_Stats.BR.3": "789", "IGD.LD.1.H.H.*.X_HW_Stats.BR.4": "123", "IGD.LD.1.H.H.*.X_HW_Stats.BS.1": "456", "IGD.LD.1.H.H.*.X_HW_Stats.BS.2": "789", "IGD.LD.1.H.H.*.X_HW_Stats.BS.3": "123", "IGD.LD.1.H.H.*.X_HW_Stats.BS.4": "456" } ] }
目标结构化表格
| host | Active | var3 |
|---|---|---|
| AAA | 1 | 123 |
| BBB | 0 | 456 |
| CCC | 1 | 789 |
| DDDD | 0 | 123 |
(注:直接处理原始JSON比先转成中间非结构化数据更高效,可节省转换步骤)
工具推荐与实现
1. jq(首选,轻量高效)
jq是专门处理JSON的命令行工具,无需中间转换,直接从原始JSON提取并格式化,单进程处理速度可达每秒数百个文件,配合并行可轻松满足70万文件/小时的需求。
单文件处理脚本
jq -r ' .Report[0] | # 按ID分组所有键值对 reduce to_entries[] as $entry ( {}; ($entry.key | split(".") | last) as $id | ($entry.key | split(".")[-2]) as $field | .[$id][$field] = $entry.value ) | # 输出表头与数据行 (["host", "Active", "var3"] | @csv), to_entries[] | [.value.HName, .value.Active, .value."X_HW_Stats.BR"] | @csv ' input.json > output.csv
批量并行处理
用xargs启动多进程,充分利用CPU资源:
# 假设所有JSON文件存放在json_files目录下 ls json_files/*.json | xargs -P 8 -I {} jq -r ' .Report[0] | reduce to_entries[] as $entry ( {}; ($entry.key | split(".") | last) as $id | ($entry.key | split(".")[-2]) as $field | .[$id][$field] = $entry.value ) | # 仅第一个文件输出表头,后续跳过 if inputs == null then (["host", "Active", "var3"] | @csv), to_entries[] | [.value.HName, .value.Active, .value."X_HW_Stats.BR"] | @csv else to_entries[] | [.value.HName, .value.Active, .value."X_HW_Stats.BR"] | @csv end ' {} >> all_output.csv
-P 8表示启动8个并行进程,可根据CPU核心数调整(如16核可设为-P 12)。
2. awk(处理中间非结构化数据)
如果已生成中间非结构化文本,用awk处理转置速度极快:
中间数据示例
1 host1 AAA 2 host2 BBB 3 host3 CCC 1 active 0 2 active 1 3 active 0 1 var3 123 2 var3 456 3 var3 789
awk脚本
BEGIN { print "host,Active,var3" } { id = $1 if ($2 ~ /host/) { host[id] = $3 } else if ($2 == "active") { active[id] = $3 } else if ($2 == "var3") { var3[id] = $3 } } END { for (id in host) { print host[id] "," active[id] "," var3[id] } }
运行方式:awk -f transpose.awk input.txt > output.csv
3. Python(多进程批量处理)
若需复杂业务逻辑,用Python配合多进程处理,注意优化IO操作:
示例代码
import json import csv from multiprocessing import Pool import os def process_file(file_path): rows = [] with open(file_path, 'r') as f: data = json.load(f) report = data['Report'][0] groups = {} for key, value in report.items(): parts = key.split('.') id = parts[-1] field = parts[-2] if id not in groups: groups[id] = {} groups[id][field] = value for g in groups.values(): rows.append([ g.get('HName', ''), g.get('Active', ''), g.get('X_HW_Stats.BR', '') ]) return rows def main(): input_dir = 'json_files' output_file = 'all_output.csv' files = [os.path.join(input_dir, f) for f in os.listdir(input_dir) if f.endswith('.json')] with Pool(processes=8) as pool: all_rows = pool.map(process_file, files) with open(output_file, 'w', newline='') as f: writer = csv.writer(f) writer.writerow(['host', 'Active', 'var3']) for rows in all_rows: writer.writerows(rows) if __name__ == '__main__': main()
性能考量
- jq:单进程每秒可处理200+文件,8进程可达到1600+文件/秒,70万文件仅需约10分钟,完全满足1小时要求。
- awk:处理文本速度比jq更快,但需先从JSON提取中间数据,适合已有中间数据的场景。
- Python:多进程下性能接近jq,代码更灵活,适合复杂逻辑需求。
内容的提问来源于stack exchange,提问作者Santo365
相关产品推荐
相关产品推荐

