如何合并多文本文件指定行:按数据点整合多文件内容
文件合并解决方案
问题场景
有4个文本文件,每个包含153个数据点,每个数据点由3行组成:
- 第1行:数据点名称
- 第2行:数据点信息
- 第3行:数据点对应文件的专属数据
需求:合并后每个数据点保留第一个文件的名称和信息行,再依次追加所有4个文件中对应数据点的第三行数据。
示例输入(简化版):
File 1:
datapoint_1_name datapoint_1_info datapoint_1_data_file1 datapoint_2_name datapoint_2_info datapoint_2_data_file1File 2:
datapoint_1_name datapoint_1_info datapoint_1_data_file2 datapoint_2_name datapoint_2_info datapoint_2_data_file2
示例输出:
datapoint_1_name datapoint_1_info datapoint_1_data_file1 datapoint_1_data_file2 datapoint_1_data_file3 datapoint_1_data_file4 datapoint_2_name datapoint_2_info datapoint_2_data_file1 datapoint_2_data_file2 datapoint_2_data_file3 datapoint_2_data_file4
原脚本问题分析
Python脚本冻结原因
你的Python脚本存在严重的嵌套循环逻辑问题:每次处理File1的一行时,都会嵌套遍历File2、File3、File4的所有行,时间复杂度为O(N^4)(N为总行数),直接导致程序卡死。同时重复的条件判断也无法准确匹配每个数据点的结构。
Awk脚本问题
你的Bash+Awk脚本每次仅提取每个文件的第3行(NR==3),而非对应数据点的第三行,因此只会重复打印固定内容,无法遍历所有数据点。
正确解决方案
方案1:Python实现
思路:先批量提取所有文件中每个数据点的第三行,按顺序存储;再遍历第一个文件的每个数据点,输出名称、信息行,然后追加所有文件对应位置的第三行。
output_file = "combined_sequences_and_data.txt" input_files = ["file1", "file2", "file3", "file4"] # 提取所有文件的每个数据点第三行,存储为列表:每个元素是对应文件的第三行列表 data_lines = [] for fname in input_files: with open(fname, 'r') as f: lines = [line.strip() for line in f if line.strip()] # 每个数据点第三行的索引是2,5,8...步长3 third_lines = [lines[i] for i in range(2, len(lines), 3)] data_lines.append(third_lines) # 处理第一个文件的名称和信息行,并合并数据 with open(input_files[0], 'r') as f1, open(output_file, 'w') as out: lines_f1 = [line.strip() for line in f1 if line.strip()] # 遍历每个数据点(每个数据点占3行) for idx in range(0, len(lines_f1), 3): # 写入名称和信息行 out.write(lines_f1[idx] + '\n') out.write(lines_f1[idx+1] + '\n') # 写入所有文件对应数据点的第三行 for dl in data_lines: out.write(dl[idx//3] + '\n')
方案2:Awk实现
思路:利用Awk的数组存储每个文件对应数据点的第三行,然后结合第一个文件的前两行输出。
#!/usr/bin/awk -f BEGIN { # 读取所有输入文件的第三行,按数据点索引存储 for (i=1; i<ARGC; i++) { fname = ARGV[i] cnt = 0 while ((getline line < fname) > 0) { if (line ~ /^$/) continue # 跳过空行 cnt++ if (cnt % 3 == 0) { data[i][int(cnt/3)] = line } } close(fname) } ARGC = 2 # 只处理第一个文件作为主输入 } # 处理第一个文件的每一行 { if ($0 ~ /^$/) next # 跳过空行 line_num++ # 存储每个数据点的前两行 if (line_num % 3 == 1) name = $0 if (line_num % 3 == 2) info = $0 # 遇到第三行时,输出完整数据块 if (line_num % 3 == 0) { print name print info # 输出所有文件对应数据点的第三行 for (i=1; i<ARGC+2; i++) { # ARGC此时是2,对应4个文件 print data[i][int(line_num/3)] } } }
使用方式:将脚本保存为merge.awk,执行命令:
awk -f merge.awk file1 file2 file3 file4 > combined.txt
内容的提问来源于stack exchange,提问作者SJP
相关产品推荐
相关产品推荐

