จับคู่คอลัมน์ของไฟล์หนึ่งกับอีกคอลัมน์หนึ่งโดยใช้ awk เมื่อคอลัมน์ไฟล์ที่สองมีเครื่องหมายจุลภาค

ฉันมีสองไฟล์ - ไฟล์หนึ่งเป็นไฟล์ขนาดใหญ่ที่มีตัวแปรในยีน โดยมีหลายคอลัมน์คั่นด้วยแท็บ คอลัมน์ที่มีชื่อยีนอาจมีชื่อเดียวหรือหลายชื่อคั่นด้วยเครื่องหมายจุลภาค (ชื่อยีนในตัวอย่างคือ SAMD11 และ NOC2L):

1   874816  874816  -   T   rs200996316 SAMD11  exonic  ENSG00000187634 frameshift insertion
1   878331  878331  C   T   rs148327885 SAMD11  exonic  ENSG00000187634 nonsynonymous SNV
1   879676  879676  G   A   rs6605067   NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976
1   879687  879687  T   C   rs2839  NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976
1   881918  881918  G   A   rs35471880  NOC2L   exonic  ENSG00000188976 nonsynonymous SNV
1   888659  888659  T   C   rs3748597   NOC2L   exonic  ENSG00000188976 nonsynonymous SNV

ไฟล์ที่สองคือรายการชื่อยีนในคอลัมน์เดียว เช่นนี้

EVC2
SAMD11
COMT

ฉันต้องการจับคู่ชื่อยีนในไฟล์ที่สองกับชื่อในไฟล์แรก ขณะนี้ฉันกำลังใช้ awk:

awk -F $'\t' 'BEGIN { while(getline <"secondfile.txt") gene[$0]=1; } gene[$7]' firstfile.txt > newfile.txt

อย่างไรก็ตาม จะพิมพ์เฉพาะรายการที่ตรงกันทุกประการเท่านั้น ดังนั้นจึงไม่พิมพ์บรรทัดที่มี NOC2L,SAMD11 จากตัวอย่างข้างต้น ผลลัพธ์ที่คาดหวังจะเป็นสี่บรรทัดแรกของไฟล์แรก:

1   874816  874816  -   T   rs200996316 SAMD11  exonic  ENSG00000187634 frameshift insertion
1   878331  878331  C   T   rs148327885 SAMD11  exonic  ENSG00000187634 nonsynonymous SNV
1   879676  879676  G   A   rs6605067   NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976
1   879687  879687  T   C   rs2839  NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976

ฉันต้องการให้มันยังคงจับคู่แบบตรงทั้งหมด เนื่องจากชื่อยีนบางชื่ออาจคล้ายกัน เช่น อาจมียีนที่เรียกว่า SAMD1 และถ้าฉันทำการจับคู่แบบคลุมเครือสำหรับสิ่งนั้น ฉันจะได้ SAMD1, SAMD11 และอื่นๆ ดังนั้นฉันจึงต้องการบางสิ่งที่ตรงกันทุกประการแต่ละเว้นเครื่องหมายจุลภาคในคอลัมน์ชื่อยีน หรือถือว่ามันเป็นตัวคั่นฟิลด์หรือคล้ายกัน

ขอบคุณล่วงหน้า.


person azule_r    schedule 25.09.2015    source แหล่งที่มา
comment
ขอบคุณครับ ทำได้แล้วครับ   -  person azule_r    schedule 26.09.2015


คำตอบ (1)


$ cat tst.awk
NR==FNR { genes[$0]; next }
{
    split($7,a,/,/)
    for (i in a) {
        if (a[i] in genes) {
            print
            next
        }
    }
}

$ awk -f tst.awk secondfile.txt firstfile.txt
1   874816  874816  -   T   rs200996316 SAMD11  exonic  ENSG00000187634 frameshift insertion
1   878331  878331  C   T   rs148327885 SAMD11  exonic  ENSG00000187634 nonsynonymous SNV
1   879676  879676  G   A   rs6605067   NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976
1   879687  879687  T   C   rs2839  NOC2L,SAMD11    UTR3    ENSG00000187634,ENSG00000188976

สิ่งนี้ก็จะได้ผลเช่นกัน:

$ cat tst.awk
NR==FNR { genes[$0]; next }
{
    for (gene in genes) {
        if ($7 ~ "(^|,)"gene"(,|$)") {
            print
            next
        }
    }
}
person Ed Morton    schedule 25.09.2015
comment
ขอบคุณ มันได้ผล! ฉันขอถามได้ไหมว่า 'a' ในการแยกกำลังทำอะไรอยู่? - person azule_r; 26.09.2015
comment
นั่นคือชื่ออาร์เรย์ที่ split() กำลังเติมข้อมูล ผู้ชาย awk และเงยหน้าขึ้นมอง split() ฉันจะโพสต์ทางเลือกสองสามทางให้คุณด้วย - อาจเป็นคำแนะนำที่ดีในการ awk เพื่อให้คุณได้เห็นวิธีแก้ไขปัญหาที่แตกต่างกัน หมายเหตุ - ไม่มีข้อใดเกี่ยวข้องกับ getline! - person Ed Morton; 26.09.2015