दो कॉलम के मिलान के आधार पर दो फ़ाइलों को कैसे मर्ज किया जाए?


33

मेरे पास फ़ाइल 1 पसंद है:

0   AFFX-SNP-000541  NA
0   AFFX-SNP-002255  NA
1   rs12103          0.6401
1   rs12103_1247494  0.696
1   rs12142199       0.7672

और एक फ़ाइल 2:

0   AFFX-SNP-000541   1
0   AFFX-SNP-002255   1
1   rs12103           0.5596
1   rs12103_1247494   0.5581
1   rs12142199        0.4931

और फ़ाइल 3 को इस तरह चाहेंगे:

0   AFFX-SNP-000541     NA       1
0   AFFX-SNP-002255     NA       1
1   rs12103             0.6401   0.5596
1   rs12103_1247494     0.696    0.5581
1   rs12142199          0.7672   0.4931

जिसका अर्थ है फ़ाइल 2 के चौथे कॉलम को 2 कॉलम के नाम से फाइल 1 में रखना।


1
File2 केवल तीन कॉलम मिला?
बर्नहार्ड

जवाबों:


48

यह करना चाहिए:

join -j 2 -o 1.1,1.2,1.3,2.3 file1 file2

महत्वपूर्ण : यह मानता है कि आपकी फाइलें एसएनपी नाम के अनुसार क्रमबद्ध हैं (आपके उदाहरण में)। यदि वे नहीं हैं, तो उन्हें पहले क्रमबद्ध करें:

join -j 2 -o 1.1,1.2,1.3,2.3 <(sort -k2 file1) <(sort -k2 file2)

आउटपुट:

0 AFFX-SNP-000541 NA 1
0 AFFX-SNP-002255 NA 1
1 rs12103 0.6401 0.5596
1 rs12103_1247494 0.696 0.5581
1 rs12142199 0.7672 0.4931

स्पष्टीकरण (से info join):

`जॉइन 'मानक आउटपुट को लिखता है, जो प्रत्येक इनपुट लाइनों की जोड़ी के लिए एक लाइन है, जिसमें समान फ़ील्ड्स शामिल होते हैं।

`-1 FIELD'
     Join on field FIELD (a positive integer) of file 1.

`-2 FIELD'
     Join on field FIELD (a positive integer) of file 2.

`-j FIELD'
     Equivalent to `-1 FIELD -2 FIELD'.

`-o FIELD-LIST'

 Otherwise, construct each output line according to the format in
 FIELD-LIST.  Each element in FIELD-LIST is either the single
 character `0' or has the form M.N where the file number, M, is `1'
 or `2' and N is a positive field number.

तो, ऊपर की कमांड दूसरी फील्ड की फाइलों से जुड़ती है और फाइल 1 के 2, 2 और 3 के फील्ड को प्रिंट करती है, उसके बाद फाइल 2 के 3 फील्ड पर जाती है।


16

आप उपयोग कर सकते हैं awk:

$ awk 'NR==FNR {h[$2] = $3; next} {print $1,$2,$3,h[$2]}' file2 file1 > file3

उत्पादन:

$ cat file3
0 AFFX-SNP-000541 NA 1
0 AFFX-SNP-002255 NA 1
1 rs12103 0.6401 0.5596
1 rs12103_1247494 0.696 0.5581
1 rs12142199 0.7672 0.4931

स्पष्टीकरण:

file2( NR==FNRपहले फ़ाइल तर्क के लिए केवल सच है) के माध्यम से चलो । कॉलम 2 को हैश-एरे में कॉलम 2 को कुंजी के रूप में सहेजें h[$2] = $3:। फिर हैश-एरे से संबंधित सहेजे गए कॉलम को जोड़ते हुए, file1सभी तीन कॉलमों $1,$2,$3से गुजरें और आउटपुट करें h[$2]


बहुत बहुत धन्यवाद। बस सोच रहा था, 'h [$ 2] = $ 3' का क्या मतलब है? वास्तव में मुझे अपने जटिल मामलों में file1 $ 2 == file2 $ 2 से बिल्कुल मेल खाने की आवश्यकता है (जो कि उसी क्रम में आवश्यक नहीं हैं)।
दादोंग जांग

1
h[$2] = $3एक हैश असाइनमेंट है। यह $3मान के $2रूप में और कुंजी के रूप में सहेजता है । उदाहरण: h["name"] = "Dadong"। अब, print h["name"]आउटपुट Dadong। यह वही करता है जो आप चाहते हैं, यह दोनों फाइलों के दूसरे कॉलम से बिल्कुल मेल खाता है।
grebneke

6

यदि आपको किसी सरल ऑर्डर की तुलना में किसी ऑर्डर की आवश्यकता नहीं है, तो

paste file{1,2} | awk '{print $1,$2,$3,$6}' > file3

यह मानता है कि सभी पंक्तियों में तीन प्रविष्टियाँ हैं, और दोनों फ़ाइलों के स्तंभ 1 और 2 एक समान हैं (जैसे आपके उदाहरण डेटा में)


1
+1 के शानदार उपयोग के लिएpaste
grebneke

1
@grebneke और बर्नहार्ड, जब से तुम के प्रशंसकों होने लगते हैं pasteआप जवाब देने के लिए एक तरह से पता लगा सकते हैं इस coreutils साथ?
terdon

@terdon - एक विनम्र प्रयास: unix.stackexchange.com/a/113909/32165
grebneke

1
@terdon मैं इस कार्यक्रम पर पुनर्विचार करने की सलाह दूंगा जो इस ***
बर्नहार्ड

प्रारूप के साथ कुछ भी गलत नहीं है, पूरी तरह से सभ्य टैब अलग फ़ाइलों। किसी भी मामले में, इस तरह के डेटा के साथ आपके पास आमतौर पर प्रारूप के रूप में कोई विकल्प नहीं है, यह किसी अन्य प्रोग्राम से बाहर आता है।
terdon
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.