किसी अन्य स्तंभ के मानों के आधार पर, स्तंभ के मानों का योग करने के लिए awk का उपयोग करना


63

मैं एक कॉलम में कुछ नंबरों का उपयोग करने की कोशिश कर रहा हूं awk। मैं कुल 212 प्राप्त करने के लिए "स्मिथ्स" के सिर्फ कॉलम 3 को समेटना चाहूंगा। मैं पूरे कॉलम का उपयोग कर सकता हूं, awkलेकिन सिर्फ "स्मिट्स" का नहीं। मेरे पास है:

awk 'BEGIN {FS = "|"} ; {sum+=$3} END {print sum}' filename.txt

इसके अलावा मैं पोटीन का उपयोग कर रहा हूं। हर प्रकार की सहायता के लिए आपका धन्यवाद।

smiths|Login|2
olivert|Login|10
denniss|Payroll|100
smiths|Time|200
smiths|Logout|10

जवाबों:


81
awk -F '|' '$1 ~ /smiths/ {sum += $3} END {print sum}' inputfilename
  • -Fझंडा क्षेत्र विभाजक बनाया; मैंने इसे एकल उद्धरणों में रखा क्योंकि यह एक विशेष शैल चरित्र है।
  • फिर $1 ~ /smiths/निम्नलिखित {कोड ब्लॉक} को केवल उन लाइनों पर लागू किया जाता है जहां पहला फ़ील्ड रेक्स से मेल खाता है /smiths/
  • शेष आपके कोड के समान है।

ध्यान दें कि चूंकि आप वास्तव में एक रेक्सक्स का उपयोग नहीं कर रहे हैं, बस एक विशिष्ट मूल्य, आप आसानी से उपयोग कर सकते हैं:

awk -F '|' '$1 == "smiths" {sum += $3} END {print sum}' inputfilename

जो स्ट्रिंग समानता की जाँच करता है। यह रेगेक्स का उपयोग करने के बराबर है /^smiths$/, जैसा कि एक अन्य उत्तर में उल्लेख किया गया है, जिसमें ^लंगर केवल स्ट्रिंग की शुरुआत (फ़ील्ड 1 की शुरुआत) $से मेल खाता है और लंगर केवल स्ट्रिंग के अंत से मेल खाता है। यकीन नहीं होता कि आप रेगेक्स से कितने परिचित हैं। वे बहुत शक्तिशाली हैं, लेकिन इस मामले के लिए आप आसानी से एक स्ट्रिंग समानता की जांच का उपयोग कर सकते हैं।


3
वैसे, मेरा go-to पसंदीदा awk संदर्भ grymoire.com/Unix/Awk.html है । बहुत उपयोगी पृष्ठ।
वाइल्डकार्ड

1
आप का शुक्र है! मैं आपकी सलाह के आधार पर बड़े ज़िप संग्रह में विशेष रूप से फ़ाइलों के एक असम्पीडित आकार को बड़े पैमाने पर एकत्र करने में सक्षम था :) unzip -lv /appl/tmp/data.lar | grep documentlibrary | awk '{sum += $1} END {print sum/1024/1024}'
Pawel

15

एक और तरीका यह है कि यहाँ पर अधिक जानकारी के लिए awk साहचर्य सरणियों का उपयोग किया जाए । यह लाइन वांछित आउटपुट का उत्पादन करती है:

awk -F '|' '{a[$1] += $3} END{print a["smiths"]}' filename.txt

साइड इफेक्ट के रूप में, सरणी अन्य सभी मूल्यों को संग्रहीत करती है:

awk -F '|' '{a[$1] += $3} END{for (i in a) print i, a[i]}' filename.txt

आउटपुट:

smiths 212
denniss 100
olivert 10

यह सही उत्तर है
PoVa

5

अब तक बहुत अच्छा। आपको योग जोड़ने के लिए ब्लॉक से पहले एक चयनकर्ता को जोड़ना होगा। यहाँ हम जाँचते हैं कि पहले तर्क में केवल "स्मिथ" हैं:

awk 'BEGIN {FS = "|"} ; $1 ~ /^smiths$/ {sum+=$3} END {print sum}'

आप क्षेत्र विभाजक को विकल्प के रूप में निर्दिष्ट करके इसे थोड़ा छोटा कर सकते हैं। में awkयह आम तौर पर एक अच्छा विचार कमांड लाइन पर चर प्रारंभ करने में बताया गया है:

awk -F'|' '$1 ~ /^smiths$/ {sum+=$3} END {print sum}'

0
cat filename.txt | grep smiths | awk -F '|' '{sum+=$NF} END {print sum}'
  • -F विभाजक निर्दिष्ट करने का विकल्प।
  • $NF "अंतिम कॉलम" के लिए है।

1
catऔर grepयहाँ अनावश्यक हैं
एंड्री

Grep को अनावश्यक क्यों ठहराया गया है? ओपी केवल "स्मिथ" पंक्तियों को जोड़ना चाहता है। आपको awk स्टेटमेंट को संशोधित करने की आवश्यकता होगी, है ना?
ईएल

1
@ हाँ, /smiths/{...}यदि grep कॉल नहीं है , तो awk स्टेटमेंट को संशोधित किया जाना चाहिए । यह एक तुच्छ संशोधन है, लेकिन यह महत्वपूर्ण लाभ प्रदान करता है: चल रही प्रक्रियाओं की संख्या घट जाती है, त्रुटि नियंत्रण को सरल करता है, और कोड को स्पष्ट करता है।
एंड्री

0

मैं व्यक्तिगत awkरूप से अनुभाग को यथासंभव सरल रखना और इसके बिना जितना संभव हो उतना करना पसंद करूंगा । कमिंग लॉजिक यूनिक्स पाइपलाइनों की शक्ति का लाभ नहीं उठाता है और इस प्रकार बारीकी से संबंधित उपयोग मामलों के लिए समझना, डीबग करना या संशोधित करना कठिन है।

cat filename.txt | perl -pe 's{.*|}{}g' | awk '{sum+=$1} END {print sum}'
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.