मेरे पास एक बड़ी फ़ाइल A (टैब सीमांकित) ~ 8 मिलियन पंक्तियों के साथ है, फ़ाइल इस तरह दिखती है:

1 10001
1 10005
1 10019
1 10055
1 10108

और एक अन्य फ़ाइल B जो इस तरह दिखती है:

#CHROM  POS ID  REF ALT QUAL    FILTER  INFO
1   10001   .   T   C   .   .   AF=0.0000384;AC=1;AN=26028;DS=SS6004475
1   10002   .   A   C,T .   .   AF=0.0001153,0.0000384;AC=3,1;AN=26028;DS=HGDP00927|HGDP00998|HGDP01284,HGDP01029
1   10002   .   A   AT  .   .   AF=0.0000384;AC=1;AN=26028;DS=HGDP00521
1   10003   .   A   C,T .   .   AF=0.0000384,0.0000768;AC=1,2;AN=26028;DS=HGDP01284,HGDP00521|HGDP00927
1   10004   .   C   A   .   .   AF=0.0000384;AC=1;AN=26028;DS=HGDP01284
1   10018   .   C   T   .   .   AF=0.0000384;AC=1;AN=26028;DS=HGDP00998
1   10019   rs775809821 TA  T   .   .   AF=0.0000384;AC=1;AN=26028;END=10020;DS=Malay
1   10055   rs768019142 T   TA  .   .   AF=0.0000384;AC=1;AN=26028;DS=Malay 
1   10108   rs62651026  C   T   .   .   AF=0.0000768;AC=2;AN=26028;DS=HGDP00778|HGDP0456

मैं जो चाहता हूं वह फ़ाइल {{X 1}} के पहले दो कॉलमों के साथ फ़ाइल A में कॉलम का मिलान करना है और A फाइल करने के लिए फ़ाइल {3rd X2}} के 3 कॉलम से जानकारी जोड़ना है। अगर कोई मैच नहीं है, तो मैं इसके बजाय एक NA आउटपुट देना चाहूंगा। वांछित आउटपुट कुछ इस तरह होगा। B फ़ाइल में # के साथ कई टिप्पणी लाइनें भी हैं जिन्हें मैं फ़ाइल को पढ़ने से बचना चाहूंगा। आउटपुट कुछ इस तरह होगा:

1 10001 .
1 10005 NA
1 10019 rs775809821
1 10055 rs768019142
1 10108 rs62651026

धन्यवाद

awk
2
user2380782 2 पद 2015, 16:23

2 जवाब

सबसे बढ़िया उत्तर

आप कुछ ऐसा लिख ​​सकते हैं

awk 'NR==FNR{line[$1" "$2]=$3; next} ($0 in line){print $0,line[$0]; next} {print $0, "NA"}' file2 file1

उदाहरण

$ awk 'NR==FNR{line[$1" "$2]=$3; next} ($0 in line){print $0,line[$0]; next} {print $0, "NA"}' file2 file1
1 10001 .
1 10005 NA
1 10019 rs775809821
1 10055 rs768019142
1 10108 rs62651026

यह क्या करता है?

  • NR==FNR{line[$1" "$2]=$3; next} यदि इनपुट फ़ाइल पहली फ़ाइल है (जिसे NR==FNR द्वारा ध्यान रखा गया है), तो हम line अनुक्रमित line को $1" "$2 द्वारा सहेजते हैं।

  • ($0 in line){print $0,line[$0]; next} दूसरी फ़ाइल के लिए, यदि वर्तमान लाइन line में है, तो file2 मान के बाद, उस लाइन को प्रिंट करें।

  • {print $0, "NA"} यदि NA के बाद लाइन प्रिंट नहीं होती है।

3
hek2mgl 2 पद 2015, 13:38

क्या आपके पहले कॉलम में केवल संख्यात्मक मूल्य हैं? क्या इनमें 1-2 अंक से अधिक होंगे? क्या आप दूसरे कॉलम में 5-9 अंकों से अधिक संख्या की उम्मीद करेंगे? क्या दोनों फाइलें संख्यात्मक रूप से क्रमबद्ध हैं (यानी sort -k1n,1 -k2n,2)? क्या प्रत्येक फ़ाइल में कॉलम 1 और 2 का संयोजन अद्वितीय है (या क्या उनमें डुप्लिकेट शामिल हैं)? यदि आप उपरोक्त सभी प्रश्नों का उत्तर हां में दे सकते हैं, तो यहां एक और समाधान है।

join -a1 -o 1.2,1.3,2.2 -e "NA" \
<(awk '{printf("%02d:%09d\t%s\t%s\n", $1, $2, $1, $2)}' A) \
<(cat B | grep -v ^# | awk '{printf("%02d:%09d\t%s\n", $1, $2, $3)}')

यदि फ़ाइल B gzipped है, तो cat B के बजाय zcat B या gunzip -c B का उपयोग करें।

0
tommy.carstensen 23 फरवरी 2017, 23:33