我有一个包含很多行的数据文件, 例如:
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;他们被删除了,所以他们不会被写入“带有区域。”文字。'
答案 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....