list_file
, file1
및 3개의 파일이 있습니다. 쌍을 기준으로 전체 행을 추출 하고 결과를 출력에 연결하고 file2
싶습니다 .file1
file2
list_file
즉, file1에서 file2
이름이 있는 줄만 추출하면 됩니다.4열첫 번째 열과 두 번째 열의 이름을 각각 일치시킨 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