मैंने निम्नलिखित करने के लिए Awk का उपयोग करने का प्रयास किया है: मेरे पास पहले कॉलम के साथ एक बड़ी txt फ़ाइल है जिसमें प्रत्येक कॉलम में एक जीन और विभिन्न मान, अनिवार्य रूप से संख्यात्मक, का नाम है। अब मेरे पास जीन की सूची वाली एक फ़ाइल है (सभी जीन नहीं, केवल एक सबसेट) जिसे मैं संशोधित करना चाहता हूं।

प्रारंभ में मैंने फ़ोरम में मिली किसी चीज़ का उपयोग करके केवल लाइनें हटा दीं

awk -F '\t' ' FILENAME=="gene_list" {arr[$1]; next}  # create an array without values 
        !($1 in arr)' gene_list original_file.txt > modified_file.txt

यह बहुत अच्छा काम करता है लेकिन अब मुझे सभी पंक्तियों (उसी क्रम में) रखने की जरूरत है, लेकिन इन जीनों को कुछ ऐसा करने के लिए संशोधित करें:

if ($1 in arr) {print $1, $2, $3-($4/10), $4}
else {print $0}

तो आप देखिए, इस बार, अगर यह अलग है (जीन मेरी सूची में नहीं है), मैं पूरी लाइन रखना चाहता हूं, अन्यथा मैं पूरी लाइन रखना चाहता हूं लेकिन एक कॉलम में मान को किसी दिए गए नंबर से संशोधित करना चाहता हूं।

यदि आप कुछ शामिल कर सकते हैं ताकि मान एक पूर्णांक बना रहे जो कि बहुत अच्छा होगा। यदि मान ऋणात्मक हो जाता है, तो मुझे 0 से प्रतिस्थापित करना होगा। लेकिन यह मुझे पता है कि कैसे करना है, कम से कम एक अलग कमांड में।

संपादित करें: न्यूनतम उदाहरण: एक txt फ़ाइल में जीन की सूची, एक के नीचे एक:

ccl5
cxcr4
setx

संशोधित करने के लिए फ़ाइल: (मैंने यहां फ़ील्ड सेपरेटर के रूप में कोमा रखा है, लेकिन फ़ील्ड को अलग करने के लिए टैब होना चाहिए)

ccl4,3,18000,50000
ccl5,4,400,5000
cxcr4,5,300,2500
apoe,4,100,90
setx,3,200,1903

अपेक्षित आउटपुट: (जब पहले कॉलम में जीन मेरी अलग txt फ़ाइल में एक जीन से मेल खाता है, तो मैं चौथे कॉलम में से 10 को हटा देता हूं, अन्यथा मैं पूरी लाइन को अपरिवर्तित रखता हूं)

ccl4,3,18000,50000
ccl5,4,0,5000
cxcr4,5,50,2500
apoe,4,100,90
setx,3,10,1903
awk
1
Dart3231 9 सितंबर 2021, 18:39
1
हाय धन्यवाद, मैंने अभी अपना प्रश्न संशोधित किया है और इसे समझना और परीक्षण करना आसान होना चाहिए।
 – 
Dart3231
10 सितंबर 2021, 12:22
स्पष्ट अनुकूलन तीसरे क्षेत्र के लिए थोड़ा अलग परिणाम प्राप्त करता है लेकिन मुझे लगता है कि यही कारण है कि आपके पास क्वालीफायर के रूप में "कुछ ऐसा" है। डेमो: ideone.com/mftzFy
 – 
tripleee
10 सितंबर 2021, 12:30
ओह हाँ यह आपके जैसा काम करता है (मुझे "अगर" डालने की आवश्यकता नहीं है, मेरे पास उचित वाक्यविन्यास नहीं था), लेकिन अब मुझे गणना द्वारा उत्पन्न फ्लोट होने पर पूर्णांक प्राप्त करने की आवश्यकता है और 0 जब यह है नकारात्मक। जबकि मैं देखता हूं कि कोड की एक नई पंक्ति में <0 तीसरे कॉलम में 0 कैसे प्राप्त करें, मुझे यकीन नहीं है कि पूर्णांक कैसे प्राप्त करें, लेकिन मुझे लगता है कि मैं इसे ढूंढ सकता हूं। क्या आप मुझे बता सकते हैं कि आपको अपने कोड की अंतिम पंक्ति में सिंगल कोट से पहले 1 की आवश्यकता क्यों है? धन्यवाद
 – 
Dart3231
10 सितंबर 2021, 12:36

1 उत्तर

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

बस अंकगणितीय बाधाओं का जादू करें।

निम्नलिखित मुहावरा Awk में इसे स्पष्ट करने का एक प्रयास है।

if (something) { print } को केवल something के रूप में पुनर्व्यवस्थित किया जा सकता है। तो बस 1 (जो हमेशा सत्य होता है) "सभी लाइनों को प्रिंट करने के लिए एक सामान्य मुहावरा है (यदि आप next मारने से पहले स्क्रिप्ट में इस बिंदु तक पहुंचते हैं)।

फ़्लोटिंग-पॉइंट नंबर को गोल करना sprintf("%1.0f", n) के साथ किया जा सकता है, जो अंश 0.5 से बड़ा होने पर सही ढंग से गोल हो जाता है (int(n) हमेशा नीचे की ओर होगा)।

awk 'BEGIN { FS=OFS="\t" }
  FILENAME=="gene_list" {arr[$1]; next}
  $1 in arr { x=sprintf("%1.0f", $3-($4/10));
    if (x<0) x=0; print $1, $2, x, $4; next }
  1' gene_list original_file.txt > modified_file.txt

डेमो: https://ideone.com/oDjKhf

1
tripleee 10 सितंबर 2021, 16:44
1
बस -F '\t' को BEGIN{FS=OFS="\t"} में बदलें क्योंकि मुझे यकीन है कि ओपी इनपुट सेपरेटर के समान आउटपुट चाहता है।
 – 
Ed Morton
10 सितंबर 2021, 15:46