如何将大txt文件中bbox开头行对应内容拆分写入同名独立文件
问题描述
输入文件格式
你有一个内容结构如下的大txt文件:
bbox_003266.txt 172.56 96.36 199.61 295.15 922.0 79.9 1242.0 349.52 378.56 128.58 803.91 234.82 701.14 176.7 862.34 285.47 bbox_003200.txt 705.95 117.81 1242.0 252.43 1036.12 183.52 1242.0 375.0 124.11 143.43 296.91 230.32 0.0 6.6 112.99 375.0 0.0 186.66 14.82 375.0
需求说明
每遇到以bbox开头的行,就将该行后续直到下一个bbox行之前的内容,写入与该行文件名同名的新文件中。以上述示例为例,最终要生成bbox_003266.txt、bbox_003200.txt两个独立文件。
现有未达预期的代码
file_in = 'final.txt' counter = 3199 with open(file_in, 'r') as fin: line = fin.readline() # read file in line by line while line: if 'bbox' in line: try: fout.close() # close the old file except: pass # augment the counter and open a new file counter += 1 fout = open('' % counter, 'w') fout.write(line) # write the line to the output file line = fin.readline() # read the next line of the input file fout.close() # close the last output file
问题分析
原代码存在3个核心问题:
- 没有读取
bbox开头行的文件名作为输出文件名,反而用自定义的counter生成文件名,和需求完全不符 - 语法错误:
with代码块下的第一行line = fin.readline()没有缩进,Python运行会直接报错 - 文件名生成的格式化字符串写法错误,
open('' % counter, 'w')是空字符串格式化,根本无法生成有效文件名
修正后可运行代码
file_in = 'final.txt' fout = None with open(file_in, 'r', encoding='utf-8') as fin: for line in fin: # 遇到bbox开头的行就切换输出文件 if line.startswith('bbox'): # 关闭之前打开的输出文件 if fout is not None: fout.close() # 取当前行的内容作为输出文件名,记得去掉末尾的换行符 output_filename = line.strip() fout = open(output_filename, 'w', encoding='utf-8') # 如果不需要把bbox文件名那行写入新文件,直接continue跳过下面的write逻辑即可 # continue # 只有当输出文件已初始化的时候才写入 if fout is not None: fout.write(line) # 关闭最后一个输出文件 if fout is not None: fout.close()
代码说明
- 直接判断行是否以
bbox开头,比模糊判断包含bbox更严谨,避免内容行里包含bbox字符串的异常情况 - 用
strip()去掉文件名前后的空白、换行符,避免生成带换行的无效文件名 - 增加了
fout是否存在的判断,避免文件开头不是bbox行时的写入报错 - 如果不需要把
bbox_xxxx.txt这行本身写入新文件,放开代码里注释的continue即可
内容的提问来源于stack exchange,提问作者reddevilsutd1
相关产品推荐
相关产品推荐

