如何用Python结合gzip直接将输出写入压缩文件?
解决方案
常见问题分析
你之前可能踩了这几个坑:
- 误用gzip打开模式:用
wb会直接覆盖文件,而你需要的是追加,得用ab模式 - 没有将字符串转为字节:gzip的二进制写入模式要求传入字节对象,不能直接写字符串
- 没正确捕获subprocess的输出,导致写入内容为空或错误
方案1:保留subprocess调用,直接写入gzip
这种方式贴近你原来的逻辑,只是把输出捕获后写入压缩文件:
import gzip import subprocess # 替换成你的实际变量 docking_type = "your_docking_type" rank = "your_rank" filename = "target_file.txt" # 执行grep+awk命令,捕获输出(text=True获取字符串) cmd = f"grep -i -m 1 'REMARK VINA RESULT:' ./output/{docking_type}/output_{filename} | awk '{{print $4}}'" proc = subprocess.run(cmd, shell=True, capture_output=True, text=True) vina_result = proc.stdout.strip() # 准备要写入的内容:结果 + 文件名,各占一行 if vina_result: # 避免空结果写入 content = f"{vina_result}\n{filename}\n" # 转成字节(gzip要求二进制输入) content_bytes = content.encode("utf-8") # 用追加模式打开压缩文件 with gzip.open(f"results_{rank}.txt.gz", "ab") as f: f.write(content_bytes)
方案2:纯Python处理(更高效,适合大量文件)
频繁调用subprocess会有性能开销,直接用Python读取文件查找目标行:
import gzip def extract_vina_score(file_path): """从文件中提取VINA结果的第4个字段""" with open(file_path, "r") as f: for line in f: line_lower = line.strip().lower() if line_lower.startswith("remark vina result:"): parts = line.split() if len(parts) >= 4: return parts[3] # Python是0索引,对应awk的$4 return None # 没找到匹配行返回None # 替换成你的实际变量 docking_type = "your_docking_type" rank = "your_rank" filename = "target_file.txt" file_path = f"./output/{docking_type}/output_{filename}" vina_score = extract_vina_score(file_path) # 写入压缩文件 with gzip.open(f"results_{rank}.txt.gz", "ab") as f: if vina_score: content = f"{vina_score}\n{filename}\n" else: # 处理无结果的情况,可自定义标记 content = f"NO_SCORE\n{filename}\n" f.write(content.encode("utf-8"))
关键注意事项
- 追加模式:必须用
ab打开gzip文件,wb会清空原有内容 - 字节转换:所有写入gzip的内容都要通过
str.encode('utf-8')转为字节对象 - 异常处理:如果处理大量文件,建议加上
try-except块捕获文件读取/写入错误
内容的提问来源于stack exchange,提问作者Tiffany Huff
相关产品推荐
相关产品推荐

