如何高效用一个大文件的值替换另一个大文件对应行的值
大文件对应行替换/合并方案(低内存占用)
针对两个百万行级的大文件,需按行对应替换/合并且无法加载全量内容到内存的场景,以下是几种高效的流式处理方案:
方案1:Shell 脚本(快速实现)
场景A:直接用FILE1的行替换FILE2对应行
通过同时打开两个文件描述符,逐行读取并输出,内存仅占用当前两行数据:
#!/bin/bash # 打开文件描述符 exec 3<"file1.json" exec 4<"file2.json" # 逐行读取并替换输出 while IFS= read -r line1 <&3 && IFS= read -r line2 <&4; do echo "$line1" done > output.json # 关闭文件描述符 exec 3<&- exec 4<&-
场景B:合并两行JSON结构
结合jq工具实现JSON对象合并(FILE1字段会覆盖FILE2同名字段),同样流式处理:
#!/bin/bash exec 3<"file1.json" exec 4<"file2.json" while IFS= read -r line1 <&3 && IFS= read -r line2 <&4; do # 合并JSON:将FILE1的内容合并到FILE2中 echo "$line2" | jq --argjson data "$line1" '. + $data' done > output.json exec 3<&- exec 4<&-
方案2:Python 脚本(灵活定制)
适合需要调整JSON结构或加入复杂逻辑的场景,利用Python原生文件流实现低内存处理:
场景A:直接替换对应行
with open('file1.json', 'r') as f1, open('file2.json', 'r') as f2, open('output.json', 'w') as out: # 逐行配对读取,直到较短文件结束 for line1, line2 in zip(f1, f2): out.write(line1)
若需处理行数不一致的情况,使用itertools.zip_longest补全行:
from itertools import zip_longest with open('file1.json', 'r') as f1, open('file2.json', 'r') as f2, open('output.json', 'w') as out: # 行数不足时用空JSON填充,可自定义fillvalue for line1, line2 in zip_longest(f1, f2, fillvalue='{}'): out.write(line1 if line1 else fillvalue)
场景B:合并/调整JSON结构
import json with open('file1.json', 'r') as f1, open('file2.json', 'r') as f2, open('output.json', 'w') as out: for line1, line2 in zip(f1, f2): try: # 解析单行JSON data1 = json.loads(line1.strip()) data2 = json.loads(line2.strip()) # 自定义合并逻辑:此处是FILE1字段覆盖FILE2 merged_data = {**data2, **data1} # 写入格式化后的JSON行 json.dump(merged_data, out) out.write('\n') except json.JSONDecodeError: # 处理无效JSON,可选跳过或写入原始行 out.write(line2)
核心注意事项
- 流式处理:所有方案均采用逐行读写,避免加载全量文件到内存,适配百万级行规模。
- 行一致性:若两个文件行数不匹配,需提前对齐或在代码中加入补全/截断逻辑。
- 性能选择:纯文本替换优先用Shell脚本;复杂JSON处理用Python更灵活。
- 错误处理:大文件易存在格式错误,需加入异常捕获避免脚本崩溃。
内容的提问来源于stack exchange,提问作者Kyle Banerjee
相关产品推荐
相关产品推荐

