根据第三个列表文件过滤两个文件的行

根据第三个列表文件过滤两个文件的行

我有 3 个文件:list_filefile1file2.我想从成对中提取整行file1file2基于list_file成对提取整行,并将结果连接到输出上。

也就是说,我只需要从 file1 中提取行且file2名称为第四栏(分别)匹配第一列和第二列的名称list_file,然后按照列表文件中显示的相同配对顺序连接输出上的整行。

名字在第 1 栏list_file存在于和file1中的名称第2栏存在list_filefile2.

列表文件:

uth1.g20066 uth2.g18511
uth1.g3149  uth2.g22348
uth1.g20067 uth2.g18512
uth1.g20068 uth2.g18514
uth1.g3154  uth2.g22355

文件1

ut1A    11256   13613   uth1.g20065
ut1A    25598   47989   uth1.g20066
ut1A    39912   40142   uth1.g3148
ut1A    40324   40617   uth1.g3149
ut1A    40699   41034   uth1.g3150

文件2

ut1B    16951   39342   uth2.g18511
ut1B    31265   31495   uth2.g22347
ut1B    31677   31970   uth2.g22348
ut1B    32052   32387   uth2.g22349
ut1B    41596   46862   uth2.g18522

期望的输出:

ut1A    25598   47989   uth1.g20066 ut1B    16951   39342   uth2.g18511
ut1A    40324   40617   uth1.g3149  ut1B    31677   31970   uth2.g22348

为了执行此任务,我尝试了下面的 python 代码,它可以工作,但是它很笨拙(很多循环),并且在大型输入文件上速度非常慢,因此最好使其更加简洁。使用全新的脚本作为替代方案(也许使用 awk)也会很有趣。谢谢。

data = open("list_file.txt")

data1 = open("file1.txt")
all_lines1 = data1.readlines() 

data2 = open("file2.txt")
all_lines2 = data2.readlines()

output = open("output.txt", "w")

for line in data:

    columns = line.split( )
    geneH1data = columns[0]
    geneH2data = columns[1]

    for line1 in all_lines1:

        columns1 = line1.split( )
        chr1 = columns1[0]
        start1 = int(columns1[1])
        end1 = int(columns1[2])
        geneH1data1 = columns1[3]

        for line2 in all_lines2:

            columns2 = line2.split( )
            chr2 = columns2[0]
            start2 = int(columns2[1])
            end2 = int(columns2[2])
            geneH2data2 = columns2[3]

            if geneH1data==geneH1data1 and geneH2data==geneH2data2:
                output.write(chr1 + " " + str(start1) + " " + str(end1) + " " + geneH1data + " " + chr2 + " " + str(start2) + " " + str(end2) + " " + geneH2data + '\n')

输出.txt

ut1A 25598 47989 uth1.g20066 ut1B 16951 39342 uth2.g18511
ut1A 40324 40617 uth1.g3149 ut1B 31677 31970 uth2.g22348

答案1

使用 GNU awk 来ARGIND

$ awk '
    ARGIND<3 { a[ARGIND,$4]=$0; next }
    ((1,$1) in a) && ((2,$2) in a) { print a[1,$1], a[2,$2] }
' file1 file2 list_file
ut1A    25598   47989   uth1.g20066 ut1B    16951   39342   uth2.g18511
ut1A    40324   40617   uth1.g3149 ut1B    31677   31970   uth2.g22348

如果您没有 GNU awk,只需将其调整为:

$ awk '
    FNR==1 { argind++ }
    argind<3 { a[argind,$4]=$0; next }
    ((1,$1) in a) && ((2,$2) in a) { print a[1,$1], a[2,$2] }
' file1 file2 list_file
ut1A    25598   47989   uth1.g20066 ut1B    16951   39342   uth2.g18511
ut1A    40324   40617   uth1.g3149 ut1B    31677   31970   uth2.g22348

然后它就可以在任何 awk 中工作。如果您希望输出以制表符分隔而不是空格分隔,只需再次调整它:

$ awk '
    BEGIN { OFS="\t" }
    FNR==1 { argind++ }
    argind<3 { a[argind,$4]=$0; next }
    ((1,$1) in a) && ((2,$2) in a) { print a[1,$1], a[2,$2] }
' file1 file2 list_file
ut1A    25598   47989   uth1.g20066     ut1B    16951   39342   uth2.g18511
ut1A    40324   40617   uth1.g3149      ut1B    31677   31970   uth2.g22348

相关内容