You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Bash/Python高效处理百万级结果文件:合并行、提取内容并排序

高效处理百万级结果文件的解决方案

针对你的需求,优先推荐Bash工具链方案,因为awk+sort都是经过高度优化的C语言实现,处理百万级文件的速度远快于Python;如果需要更灵活的逻辑,也提供Python的内存友好型方案。

一、Bash快速处理方案

这个命令可以一站式完成格式转换、字段提取和排序,完全适配你的文件结构:

awk '/^Ligand:/ { 
    # 提取配体文件名(去掉路径前缀)
    ligand = $2; 
    sub(/.*\//, "", ligand) 
} /^1/ { 
    # 提取数值字段,和配体名组合输出
    print $2, ligand 
}' results.txt | sort -n

工作原理:

  1. awk处理逻辑:
    • 匹配以Ligand:开头的行,提取第二个字段(完整路径),用sub去掉所有路径前缀,只保留文件名(比如ZINC00001677.pdbqt),存到变量ligand中。
    • 匹配以1开头的数值行,提取第二个字段(即你的评分值),和之前保存的配体名一起打印。
  2. sort -n排序:
    • -n参数表示按数值升序排序,正好满足你“从最负到最正”的需求(负数数值越小,排序越靠前)。

性能优势:

  • awk逐流式处理文件,不需要加载整个文件到内存,对大文件友好。
  • GNU sort针对超大文件做了外部排序优化,能高效处理数百万行数据,比Python的排序速度快数倍。

二、Python内存友好型方案

如果你更熟悉Python,或者需要后续扩展更多逻辑,可以用生成器逐行处理,避免内存溢出:

def process_and_sort_results(input_path, output_path):
    def yield_score_ligand():
        with open(input_path, 'r') as f:
            line_iter = iter(f)
            for line in line_iter:
                line = line.strip()
                if not line.startswith('Ligand:'):
                    continue
                # 提取配体文件名(分割路径取最后一段)
                ligand_full_path = line.split()[-1]
                ligand_name = ligand_full_path.split('/')[-1]
                # 读取对应的数值行
                try:
                    score_line = next(line_iter).strip()
                except StopIteration:
                    break  # 处理文件末尾不完整的情况
                # 提取评分值
                score_parts = score_line.split()
                if len(score_parts) < 2:
                    continue
                try:
                    score = float(score_parts[1])
                except ValueError:
                    continue
                yield (score, ligand_name)
    
    # 按数值升序排序(最负的在前)
    sorted_results = sorted(yield_score_ligand(), key=lambda x: x[0])
    
    # 写入结果
    with open(output_path, 'w') as f:
        for score, ligand in sorted_results:
            f.write(f"{score} {ligand}\n")

# 调用示例
process_and_sort_results('results.txt', 'final_results.txt')

工作原理:

  • 用生成器yield_score_ligand()逐行读取文件,成对处理配体行和数值行,每次只在内存中保留一组数据。
  • sorted()函数会自动处理大数量的排序(Python的Timsort算法效率很高),最后批量写入结果文件。

额外优化建议:并行脚本的IO优化

你当前的并行脚本中,每个进程都用tee -a results.txt写入同一个文件,会导致严重的IO竞争,不仅速度慢,还可能出现数据错乱。更高效的做法是:

  1. 每个Python脚本将自己的输出写入独立的临时文件(比如result_${PID}.txt)。
  2. 所有任务完成后,用cat result_*.txt合并所有临时文件,再用上面的处理命令生成最终结果。

这样能大幅提升并行任务的IO效率,避免多进程写同一个文件的冲突。

内容的提问来源于stack exchange,提问作者darrowboat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 17:15:47