如何将CSV转换为嵌套JSON结构及恢复原有JSON格式?
嘿,这个问题我太熟了——把JSON转成CSV编辑后再转回来,嵌套结构直接乱成一锅粥,简直是日常数据处理的噩梦!别担心,咱们一步步把它恢复成和原JSON一模一样的嵌套结构。
首先得搞清楚你的CSV里那些奇怪的列名是什么意思:比如more/0/optionId,其实就是原JSON里more数组的第0个元素下的optionId字段,斜杠就是嵌套路径的分隔符。咱们的核心思路就是解析这些路径,把CSV里的值对应塞回嵌套的数组和对象里。
下面我给你用Python写个实用的脚本,直接就能用,还能根据你的需求调整:
第一步:准备Python环境
确保你已经装了Python(3.x版本就行),不需要额外装库,自带的csv和json模块足够用。
第二步:编写转换脚本
import csv import json def set_nested_value(data, path, value): """根据路径设置嵌套结构的值""" current = data # 拆分路径,比如把"more/0/optionId"拆成["more", "0", "optionId"] parts = path.split('/') # 遍历路径的前n-1个部分,构建嵌套结构 for part in parts[:-1]: if part.isdigit(): # 如果是数字,说明是数组索引,确保数组长度足够 idx = int(part) while len(current) <= idx: current.append({}) current = current[idx] else: # 如果是字符串,创建或访问对象的键 if part not in current: # 判断下一个路径部分是不是数组,来决定当前值是对象还是空值 next_part = parts[parts.index(part)+1] current[part] = [] if next_part.isdigit() else {} current = current[part] # 处理最后一个路径部分的值,做类型转换 final_part = parts[-1] # 处理布尔值 if value.lower() in ['true', 'false']: current[final_part] = value.lower() == 'true' # 处理整数和浮点数 elif value.replace('.', '', 1).isdigit(): current[final_part] = float(value) if '.' in value else int(value) # 处理空值(CSV里的空单元格或省略号) elif value.strip() == '' or value == '...': current[final_part] = None # 其他情况保留字符串 else: current[final_part] = value def csv_to_nested_json(csv_file, json_file): """把CSV转换为嵌套JSON""" result = [] with open(csv_file, 'r', encoding='utf-8') as f: reader = csv.DictReader(f) for row in reader: item = {} for col_name, value in row.items(): if value.strip() == '' and col_name not in ['active']: # 可根据需求调整忽略的空值 continue set_nested_value(item, col_name, value) result.append(item) # 写入JSON文件,格式化输出更易读 with open(json_file, 'w', encoding='utf-8') as f: json.dump(result, f, indent=2, ensure_ascii=False) # 替换成你的CSV路径和要输出的JSON路径 csv_to_nested_json('your_data.csv', 'restored_data.json')
第三步:调整和测试
- 类型转换:如果你的原JSON有日期等特殊类型,需要在
set_nested_value函数里添加对应的转换逻辑。 - 空值处理:脚本里把CSV的空单元格和
...转成了null,如果原JSON里是其他处理方式(比如空字符串),可以修改对应的代码。 - 数组填充:如果CSV里的数组索引有缺失(比如跳过了
more/1直接到more/2),脚本会自动在more[1]的位置创建一个空对象,这和大多数JSON的结构是一致的,如果不需要的话可以调整逻辑。
其他工具选项
如果你不想写代码,也可以用命令行工具组合处理,但灵活性不如Python脚本高:
- 先用
csvkit把CSV转成扁平JSON:# 先安装csvkit:pip install csvkit csvjson your_data.csv > flat_data.json - 再用
jq重组嵌套结构(需要手动对应每个路径):jq 'map(. + {more: [ {optionId: ."more/0/optionId", price: ."more/0/price"}, {optionId: ."more/1/optionId", price: ."more/1/price"}, {optionId: ."more/2/optionId", price: ."more/2/price"} ] | del(.[] | select(.optionId == null or .price == null))} | del(."more/0/optionId", ."more/0/price", ."more/1/optionId", ."more/1/price", ."more/2/optionId", ."more/2/price"))' flat_data.json > restored_data.json
这种方式适合结构固定的小数据,数据量大或者结构多变的话还是Python脚本更省心。
总之,用上面的Python脚本基本就能完美恢复你原有的嵌套JSON结构啦!
内容的提问来源于stack exchange,提问作者James Deaken
相关产品推荐
相关产品推荐

