如何覆盖文件?

How to overwrite a file?

这个问题直接链接到我的“How to modify a tsv-file column with Python”问题。简而言之:我想通过将某个符号 (in_char) 更改为另一个符号 (out_char) 来覆盖 TSV 文件的第一列。 为了覆盖原始文件,我想通过这样写来使用 .truncate() 方法:

with open(my_file, "r+") as mf:
    lines = [line.rstrip() for line in mf]
    for line in lines:
        line = line.replace(in_char, out_char, 1)
        mf.seek(0)
        mf.write(line)
        mf.truncate()
mf.close()

实际上文件被正确覆盖,但只覆盖了 TSV 的最后一行,所以我基本上获得了一行 TSV。

例如,如果我的 in_char 是“|”符号,我的 out_char 是“_”符号,来自我原来的 TSV:

A|circ  properties  m4  298 298 28  +   .   coverage=81;
B|circ  properties  m4  307 307 40  -   .   coverage=74;
C|circ  properties  m4  361 361 23  +   .   coverage=77;

这是我得到的:

C_circ  properties  m4  361 361 23  +   .   coverage=77;

我哪里做错了?

问题是您在阅读文件时正在修改文件。我建议您采用以下两种方法之一:

  1. 将整个文件读入内存,进行修改,然后将文件写回。

  2. 创建一个要写入的临时文件。一次读取输入文件一行,进行更改并将每一行写入临时文件。然后将临时文件重命名回原来的文件。

顺便说一句,我建议为此使用标准 csv 模块。特别是,DictReaderDictWriter 使这项任务变得简单。

您可以使用 pandas 加载文件并更新值:

import pandas as pd

df = pd.read_csv(input_file, sep='\t', header=None)
df[0] = df[0].str.replace('|','_')

要保存回文件:

df.to_csv(output_file, sep='\t')

假设没有 header,如果您有一个列 header,请使用它代替下标中的 0,例如 df['col1']