将行写入文件并删除python

时间:2016-02-29 20:26:22

标签: python

我有一个包含很多行的数据文件, 例如:

line1
line2
line3
line4
line5
line6
No D
line7
line8
line9
line10
line11
line12
...

每当程序看到“没有D'”的行时,我希望它在“D&D”之前写下4行。在“D&D”之后的第2行和第2行。换行到名为" NoDregion.txt" ,并将剩下的内容写入名为" WithDregion.txt"的文件中。

我的代码:

lines =open("file.txt", "r").read().splitlines()
manualintervf = open("NoDregion.txt", "w")
goodlines = open("withDregion.txt", "w")

for i, line in enumerate(lines):
    if ">No D" in line:
        manualintervf.write(lines[i-4]+"\n"+lines[i-3]+"\n"+lines[i-2]+"\n"+lines[i-1]+"\n"+lines[i]+"\n"+lines[i+1]+"\n"+lines[i+2]+"\n")
    else:
        goodlines.write(line+"\n")

NoDregion.txt" (没问题):

line3
line4
line5
line6
No D
line7
line8

在' withDregion.txt" (不是所需的输出,它只删除' No D'线并保留其他所有内容,甚至是' No D'之前的4行以及该行后的2行): / p>

line1
line2
line3
line4
line5
line6
line7
line8
line9
line10
line11
line12
...

" WithDregion.txt"的所需输出将是:

line1
line2
line9
line10
line11
line12
...

我不知道怎么写它以便在将这些行写入' NoDregion.txt后#39;他们被删除了,所以他们不会被写入“带有区域。”文字。'

3 个答案:

答案 0 :(得分:1)

您看到自己行为的原因是“No D”附近的行本身不包含“No D”,因此它们会被您的“else”子句捕获。

最简单的方法是两次通过线路。不是立即将每一行写入“D区域”或“无D区域”文件,而是设置“D区域”标志,然后将标记的行写入“D区域”,将非标记的行写入“无D区域” ”。像这样:

lines =open("S011_PCR_ABCDEF-AnnotatedVDJAlignments.fasta", "r").read().splitlines()
manualintervf = open("NoDregion.txt", "w")
goodlines = open("withDregion.txt", "w")

d_before = 4
d_after = 3
d_flag = [0] * len(lines)

for i, line in enumerate(lines):
    if "No D" in line:
        dstart = max(i-d_before, 0)
        dend = min(i+d_after, len(lines))
        for j in range(dstart, dend):
          d_flag[j] = 1

for i, line in enumerate(lines):
    if d_flag[i] == 1:
        manualintervf.write(line+"\n")
    else:
        goodlines.write(line+"\n")

无论您使用何种方法,如果您的文件的第一行或最后一行都有“No D”,您将要确保您的代码不会失败。如果您将“No D”作为文件的第一行,您将向NoDRegion写lines[-3],这几乎肯定不是您想要的,如果它是您要尝试的最后一行访问一条不存在的行,这绝对不是你想要的。

答案 1 :(得分:0)

使用此代替if/else

for i, line in enumerate(lines):
    if ">No D" in line:
         manualintervf.write(lines[i-4]+"\n"+lines[i-3]+"\n"+lines[i-2]+"\n"+lines[i-1]+"\n"+lines[i]+"\n"+lines[i+1]+"\n"+lines[i+2]+"\n")
         goodlines.write("\n".join(lines[i+1:]))

这对字符串使用join方法。尝试:"seperator".join(str(i) for i in range(10))来了解它是如何工作的。基本上它需要一个列表,并在每个元素之间将seperator(或任何你想要的字符串)连接在一起。

答案 2 :(得分:0)

由于您正在将整个文件读入内存,因此您也可以使用文件中字符串的正则表达式。

尝试:

import re

with open(fn) as f:
    txt=f.read()
    txt=re.sub(r'(?:^.*\s){4}^No D.*$\s(?:^.*\s){2}', '', txt, flags=re.M)
    # now just write txt to the output file...

或者,您可以在文件行列表中找到每个元素,如下所示:

with open(fn) as f:
    lines=f.readlines()
    while True:
        try:
            idx=lines.index('No D\n')
            lines=lines[0:idx-4]+lines[idx+2:]
        except ValueError:
            txt=''.join(lines)
            break    

     # again, just write txt out to the output file....