세 번째 목록 파일을 기반으로 두 파일의 행을 필터링합니다.

세 번째 목록 파일을 기반으로 두 파일의 행을 필터링합니다.

list_file, file1및 3개의 파일이 있습니다. 쌍을 기준으로 전체 행을 추출 하고 결과를 출력에 연결하고 file2싶습니다 .file1file2list_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

관련 정보