如何在两个文件之间以及匹配项之后的行中写入匹配行

How can I write matching lines between two files as well as the line which follows a match

我有两个要比较的 fastq 文件。 fastq文件的结构如下(per read):

我正在处理的两个文件是:

我需要比较文件 1 和 2 以找到所有匹配的 header 行,然后从文件 2 中保存相应的序列行。

其中文件 1:

@HWI-D00461:137:C9H2FACXX:3:1101:1239:1968 1:N:0:GGCTAC
NTGTGTAATAGATTTTACTTTTGCCTTTAAGCCCAAGGTCCTGGACTTGAAACATCCAAGGGATGGAAAATGCCGTATAACAGGGTGGAAGAGAGATTTGA
@HWI-D00461:137:C9H2FACXX:3:1101:1117:1968 1:N:0:GGCTAC
NAAAGTCTACCAATTATACTTAGTGTGAAGAGGTGGGAGTTAAATATGACTTCCATTAATAGTTTCATTGTTTGGAAAACAGAGGTAATTTTTGATACAGA
@HWI-D00461:137:C9H2FACXX:3:1101:1087:1973 1:N:0:GGCTAC
NTAATCCAACTAACTAAAAATAAAAAGATTCAAATAGGTACAGAAAACAATGAAGGTGTAGAGGTGAGAAATCAACAGGATGTTCAGAAGCCTGTGTATGA

和文件 2:

@HWI-D00461:137:C9H2FACXX:3:1101:1239:1968 1:N:0:GGCTAC
NTGTGTAATAGATTTTACTTTTGCCTTTAAGCCCAAGGTCCTGGACTTGAAACATCCAAGGGATGGAAAATGCCGTATAACAGGGTGGAAGAGAGATTTGN
+
#1=BDDFFHHHFHIJJJJJJJJJJJJJJJJJJJJJIJJIJJJJJHJIIJHGIJJJJJJIHJJBGHJHIIJJJHHHHFFFFEEEDD;?BACDDDA?@CDDDC
@HWI-D00461:137:C9H2FACXX:3:1101:1117:1968 1:N:0:GGCTAC
NAAAGTCTACCAATTATACTTAGTGTGAAGAGGTGGGAGTTAAATATGACTTCCATTAATAGTTTCATTGTTTGGAAAACAGAGGTAATTTTTGATACNNN
+
#1=DDDFDFHHHGHIIGJJJJHIJIHHDIHHIJGGEI@GFGHIHIJHEFHIIIIGIJGHHGECFGIDHGIHIIEGIIJHHEEFFF7?ACEECCBBDEDDDC
@HWI-D00461:137:C9H2FACXX:3:1101:1200:1972 1:N:0:GGCTAC
NTACGTTTAGTAGAGACAGTGTCTTGCTATGTTGCCCAGGCTGGTCTCAAACTCCTGAGCTCTAGCAAGCCTTCCACCTCTGCCTCCCAGTGTTCTGGGAT
+
#1=DDDDFHHHBHGIGIIJHCDHHIJJJHEGFIIHFHGEGHJEIFHHHEFHHGIGIJEHIIJJJJIJIJIJGIIH.?CEFFFFDCEDD3>>@CDDDDDD<@

换句话说,对于每个匹配的 header 行,我想保存它的配对序列行。

最后,我想把这些header和序列都写到一个新文件中,供下游分析。

我当前的输出是:

@HWI-D00461:137:C9H2FACXX:3:1101:1357:1984 1:N:0:GGCTAC
@HWI-D00461:137:C9H2FACXX:3:1101:1755:2000 1:N:0:GGCTAC
@HWI-D00461:137:C9H2FACXX:3:1101:1260:1977 1:N:0:GGCTAC
@HWI-D00461:137:C9H2FACXX:3:1101:1917:1984 1:N:0:GGCTAC

我想要的输出是:

@HWI-D00461:137:C9H2FACXX:3:1101:1239:1968 1:N:0:GGCTAC
NTGTGTAATAGATTTTACTTTTGCCTTTAAGCCCAAGGTCCTGGACTTGAAACATCCAAGGGATGGAAAATGCCGTATAACAGGGTGGAAGAGAGATTTGA
@HWI-D00461:137:C9H2FACXX:3:1101:1117:1968 1:N:0:GGCTAC
NAAAGTCTACCAATTATACTTAGTGTGAAGAGGTGGGAGTTAAATATGACTTCCATTAATAGTTTCATTGTTTGGAAAACAGAGGTAATTTTTGATACAGA
@HWI-D00461:137:C9H2FACXX:3:1101:1087:1973 1:N:0:GGCTAC
NTAATCCAACTAACTAAAAATAAAAAGATTCAAATAGGTACAGAAAACAATGAAGGTGTAGAGGTGAGAAATCAACAGGATGTTCAGAAGCCTGTGTATGA

这是我目前的情况。

ids = ''
with open(no_adapter_file, 'r') as file1:
    with open(comparison_file, 'r') as file2:
        common = set(file1).intersection(file2)
        for line in common:
            if line[0] == '@'
                ids += line

with open(comparison_file, 'r') as file2:
    ids_seq = ''
    for line in file2:
        if line == ids:
            line += ids_seq

with open(new_file, 'w') as file_out:
    for line in ids_seq:
        file_out.write(line)
print(new_file + " was created.")

代码成功提取了所有匹配的 header 行,但我不知道如何提取后面的序列行。

编辑:添加了一些输入和预期输出示例。

有多种方法可以解决您的问题。这是一个不假设文件排序的方法(这对于避免潜在的高内存消耗非常有用)。它还不考虑具有重复 ID 的可能性(如果不能保证读取顺序相同,这也可以减少内存占用)。

# First, get the IDs we are interested in
ids = set()
with open(no_adapter_file, 'r') as file1:
    line_number = 0
    for line in file1:
        line_number += 1
        if line_number % 2 == 1:
            ids.add(line.rstrip())

# Now, read the second file and print desired info if the ID is
# one of the interesting ones
with open(comparison_file, 'r') as file2, open(new_file, 'w') as file_out:
    line_number = 0
    for line in file2:
        line_number += 1
        if line_number % 4 == 1:
            candidate_id = line.rstrip()
        elif line_number % 4 == 2:
            candidate_seq = line.rstrip()
            if candidate_id in ids:
                file_out.write("{}\n{}\n".format(candidate_id, candidate_seq))

print(new_file + " was created.")

在这段代码中,我们首先读取第一个文件并将 ID 存储在一个集合中。然后,此集合用于检查是否必须写入来自第二个文件的读取。