list_file
、file1
および3つのファイルがあります。ペアに基づいて行全体を抽出し、結果を出力にリンクしたいとfile2
思います。file1
file2
list_file
つまり、file1からfile2
名前のある行を抽出するだけです。4列最初の列と2番目の列の名前をそれぞれ一致させ、list_file
リストファイルに表示されているのと同じペアの順序で出力の行全体を連結します。
名前を入力する列1list_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