修改AWK脚本:按900MB分割XML文件替代按行数分割
AWK脚本修改方案:按文件大小分割XML(单文件≤900MB)
核心逻辑
由于每个XML节点都是完整的<ent>...</ent>行,我们通过跟踪当前输出文件的字节大小,确保单个文件不超过900MB,同时保证节点不被拆分。当写入一个节点后文件大小接近阈值时,关闭当前文件,新建文件并写入XML头部,再继续写入后续节点。
修改后的AWK脚本
BEGIN { # 设定每个文件的最大大小:900MB = 900 * 1024 * 1024 字节 max_size = 900 * 1024 * 1024 file_num = 0 new_chunk = 1 } # 读取XML根节点作为头部,并生成对应的尾部 NR == 1 { header = $0 footer = "</" substr($1, 2) ">" next } # 处理每个<ent>节点行 /<ent>/ { # 如果是新文件,先创建文件并写入头部 if (new_chunk) { file_num++ outfile = "ent_" sprintf("%07d", file_num) ".xml" print header > outfile # 获取头部的字节大小(+1是换行符的字节数) current_size = length(header) + 1 new_chunk = 0 } # 计算当前节点的字节大小(+1是换行符) line_size = length($0) + 1 # 如果写入当前节点会超过阈值,先关闭当前文件,新建文件 if (current_size + line_size > max_size) { print footer > outfile close(outfile) file_num++ outfile = "ent_" sprintf("%07d", file_num) ".xml" print header > outfile current_size = length(header) + 1 } # 写入当前节点并更新文件大小 print > outfile current_size += line_size next } # 处理非<ent>的行(保留原脚本兼容逻辑) $0 !~ footer { if (!new_chunk) { line_size = length($0) + 1 if (current_size + line_size > max_size) { print footer > outfile close(outfile) file_num++ outfile = "ent_" sprintf("%07d", file_num) ".xml" print header > outfile current_size = length(header) + 1 } print > outfile current_size += line_size } } # 脚本结束时,关闭最后一个文件并写入尾部 END { if (!new_chunk) { print footer > outfile close(outfile) } }
关键修改说明
- 大小阈值设置:将原脚本的行数阈值替换为字节数阈值,直接指定900MB对应的字节数。
- 文件大小跟踪:新增
current_size变量,实时统计当前输出文件的字节总量(包含换行符)。 - 节点拆分判断:每次写入节点前,先计算节点大小与当前文件大小的和,若超过阈值则切换新文件,确保节点完整。
- 文件计数逻辑:改用
file_num变量记录分割后的文件序号,替代原有的行数计数逻辑。 - 编码兼容提示:脚本中
length()默认返回字符数,若XML是UTF-8编码(多字节字符),需根据实际情况调整字节数计算方式。
内容的提问来源于stack exchange,提问作者Christy
相关产品推荐
相关产品推荐

