我有 3 个文件:list_file
、file1
和file2
.我想从成对中提取整行file1
并file2
基于list_file
成对提取整行,并将结果连接到输出上。
也就是说,我只需要从 file1 中提取行且file2
名称为第四栏(分别)匹配第一列和第二列的名称list_file
,然后按照列表文件中显示的相同配对顺序连接输出上的整行。
名字在第 1 栏list_file
存在于和file1
中的名称第2栏存在list_file
于file2
.
列表文件:
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