यहां आपको एक
पास
कदम awk समाधान -
awk 'NR==FNR{a = a + $2;next} {c = ($2/a)*100;print $1,$2,c }' file file
[jaypal:~/Temp] cat file
1 10
2 10
3 20
4 40
[jaypal:~/Temp] awk 'NR==FNR{a = a + $2;next} {c = ($2/a)*100;print $1,$2,c }' file file
1 10 12.5
2 10 12.5
3 20 25
4 40 50
अद्यतन: यदि टैब एक उत्पादन में आवश्यक है तो बस ओएफएस चर "\ t" करने के लिए निर्धारित किया है।
[jaypal:~/Temp] awk -v OFS="\t" 'NR==FNR{a = a + $2;next} {c = ($2/a)*100;print $1,$2,c }' file file
1 10 12.5
2 10 12.5
3 20 25
4 40 50
पैटर्न {कार्रवाई} बयान के ब्रेकआउट:
पहले पैटर्न NR==FNR
है। एफएनआर अजीब अंतर्निहित चर है जो किसी दिए गए फ़ाइल में रिकॉर्ड्स की संख्या (डिफ़ॉल्ट रूप से एक नई लाइन से अलग किया जाता है) का ट्रैक रखता है। तो हमारे मामले में एफएनआर होगा 4. एनआर एफएनआर के समान है लेकिन यह 0 पर रीसेट नहीं होता है। यह बढ़ता जा रहा है। तो हमारे मामले में एनआर 8.
यह पैटर्न केवल पहले 4 रिकॉर्ड के लिए सच होगा और यह वही है जो हम चाहते हैं। 4 रिकॉर्ड के माध्यम से समझने के बाद, हम कुल को एक चर a
पर असाइन कर रहे हैं। ध्यान दें कि हमने इसे प्रारंभ नहीं किया था। awk
में हमें यह नहीं करना है। हालांकि, अगर पूरे कॉलम 2 0 है तो यह तोड़ देगा। तो आप दूसरे एक्शन स्टेटमेंट में एक कथन कथन डालकर इसे संभाल सकते हैं। मैं केवल विभाजन करता हूं यदि कोई> 0 अन्य 0 या कुछ से विभाजन कहता है।
next
आवश्यक है क्योंकि हम वास्तव में निष्पादित करने के लिए दूसरे पैटर्न {action} कथन नहीं चाहते हैं। next
आगे की कार्रवाइयों को रोकने और अगले रिकॉर्ड में जाने के लिए अजीब बताता है।
एक बार चार रिकॉर्ड पार्स किए जाने के बाद, अगला पैटर्न {action} शुरू होता है, जो कि बहुत सीधे आगे है। प्रतिशत के साथ प्रतिशत और प्रिंट कॉलम 1 और 2 के साथ प्रतिशत के साथ।
नोट:टिप्पणी में आपका उल्लेख @lhf रूप में, यह एक लाइनर केवल जब तक आप डेटा किसी फ़ाइल में निर्धारित किया है के रूप में काम करेंगे। यदि आप पाइप के माध्यम से डेटा पास करते हैं तो यह काम नहीं करेगा।
टिप्पणी में, वहाँ एक चर्चा तरीके एक pipe
बजाय एक file
से इस इनपुट awk one-liner
ले बनाने के लिए चल रहा है। वैसे मैं एकमात्र तरीका सोच सकता था कि कॉलम मानों को array
में संग्रहीत करना था और उसके बाद प्रत्येक मान को उनके प्रतिशत के साथ थूकने के लिए for loop
का उपयोग करना था।
अब arrays
awk
में associative
यानी सरणियों से बाहर मूल्यों खींच उसी क्रम में नहीं होगा के रूप में वे में चला गया। तो अगर यह ठीक उसके बाद निम्न एक लाइनर काम करना चाहिए है कर रहे हैं और क्रम में कभी नहीं कर रहे हैं।
[jaypal:~/Temp] cat file
1 10
2 10
3 20
4 40
[jaypal:~/Temp] cat file | awk '{b[$1]=$2;sum=sum+$2} END{for (i in b) print i,b[i],(b[i]/sum)*100}'
2 10 12.5
3 20 25
4 40 50
1 10 12.5
उन्हें क्रम में पाने के लिए आपको पाइप sort
लिए परिणाम कर सकते हैं।
[jaypal:~/Temp] cat file | awk '{b[$1]=$2;sum=sum+$2} END{for (i in b) print i,b[i],(b[i]/sum)*100}' | sort -n
1 10 12.5
2 10 12.5
3 20 25
4 40 50
यह है। धन्यवाद! – Martin
कोई समस्या नहीं है। :) मैं संदर्भ के लिए कुछ स्पष्टीकरण में डाल देंगे। –
अच्छा, लेकिन वास्तव में एक-पास नहीं है। विशेष रूप से, इसे फ़िल्टर के रूप में उपयोग नहीं किया जा सकता है, यानी, stdin से पढ़ना। – lhf