यूनिट प्रत्यय के साथ संख्याओं के लिए आसान पार्सिंग?


10

मान लें कि आपके पास मानव-पठनीय प्रारूप में मात्राओं के साथ डेटा है, जैसे कि आउटपुट du -h, और उन संख्याओं पर आगे काम करना चाहते हैं। मान लें कि आप उस डेटा के उप-सेट का एक योग करने के लिए grep के माध्यम से अपने डेटा को पाइप करना चाहते हैं। आप इस प्रणाली को कई प्रणालियों पर करते हैं जिन्हें आपने पहले कभी नहीं देखा है, और केवल न्यूनतम उपयोगिताओं हैं। आप सभी मानक 10 ^ n प्रत्ययों के लिए प्रत्यय रूपांतरण चाहते हैं।

एक पाइपलाइन के भीतर प्रत्यय संख्याओं को वास्तविक संख्याओं में बदलने के लिए एक गन्नू-लिनक्स उपयोगिता मौजूद है? क्या आपके पास ऐसा करने के लिए बैश फंक्शन है, या कुछ पर्ल जो रीगेक्स रिप्लेसमेंट या कई सेड स्टेप्स की लंबाई के बजाय याद रखना आसान हो सकता है?

38M     /var/crazyface/courses/200909-90147
2.7M    /var/crazyface/courses/200909-90157
1.1M    /var/crazyface/courses/200909-90159
385M    /var/crazyface/courses/200909-90161
1.3M    /var/crazyface/courses/200909-90169
376M    /var/crazyface/courses/200907-90171
8.0K    /var/crazyface/courses/200907-90173
668K    /var/crazyface/courses/200907-90175
564M    /var/crazyface/courses/200907-90178
4.0K    /var/crazyface/courses/200907-90179

| grep 200907 | <amazing suffix conversion> | awk '{s+=$1} END {print s}'


प्रासंगिक संदर्भ:


2
आपको शायद ही कभी grep और awk का उपयोग करने की आवश्यकता होती है। यदि आप awk का उपयोग कर रहे हैं, तो awk का उपयोग करें। बस /200907/अपने प्रति-पंक्ति कोड के सामने जोड़ें , जैसेawk '/200907/{s+=$1} END {print s}'
टोनी

जवाबों:


14

आपके द्वारा जुड़े सवालों में से एक पर मेरे जवाब के आधार पर:

awk '{
    ex = index("KMGTPEZY", substr($1, length($1)))
    val = substr($1, 0, length($1) - 1)

    prod = val * 10^(ex * 3)

    sum += prod
}
END {print sum}'

एक और तरीका जो प्रयोग किया जाता है:

sed 's/G/ * 1000 M/;s/M/ * 1000 K/;s/K/ * 1000/; s/$/ +\\/; $a0' | bc

दूसरी विधि के लिए, यदि प्रत्यय s है तो क्या होगा?
डेजारेज़

@djuarez: किस गुणक के लिए खड़ा है?
अगली सूचना तक रोक दिया गया।

कोई नहीं, बस अन्य यूनिट मामलों पर एक्सट्रपलेशन करना।
डेजारेज़

@ डजारेज़: इसका कोई मतलब नहीं है। यह उत्तर एसआई प्रत्ययों के बारे में है, सामान्य इकाइयों (सेकंड, शायद?) के बारे में नहीं। sedमेरे उत्तर में कमांड का विस्तार करने के लिए , आप अतिरिक्त SI प्रत्यय को संभालने के लिए क्लॉज जोड़ेंगे जैसा कि मैं awkकमांड में दिखाता हूं । s/T/ * 1000 G;उदाहरण के लिए शुरुआत में टेराबाइट्स को जोड़ा जाएगा।
अगली सूचना तक रोक दिया गया।

3

ऐसा करने के लिए आप पर्ल रेगुलर एक्सप्रेशन का उपयोग कर सकते हैं। उदाहरण के लिए,

$value = 0;
if($line =~ /(\d+\.?\d*)(\D+)\s+/) {
   $amplifier = 1024 if ($2 eq 'K');
   $amplifier = 1024 * 1024 if ($2 eq 'M');
   $amplifier = 1024 * 1024 * 1024 if ($2 eq 'G');
   $value = $1 * $amplifier;
}

यह एक साधारण स्क्रिप्ट है। आप इसे प्रारंभिक बिंदु मान सकते हैं। आशा है कि यह मदद करेगा!


वास्तव में, यह एक तरीका है। मैंने stackoverflow.com/questions/2557649/… भी पाया है ।
सेम

3

व्यक्तिगत रूप से, मैं -h ध्वज का उपयोग पहली जगह में नहीं करूंगा। "मानव पठनीय" संस्करण संख्याओं को राउंड ऑफ करता है जिसे फिर से राउंड करने की आवश्यकता होगी जब आप वापस कन्वर्ट करते हैं, और भी कम सटीक। (उदाहरण के लिए, 2.7MiB 2831155.2 बाइट्स है। आपने बाइट के अन्य 0.8 वें भाग के साथ क्या किया?)!

अन्यथा, आप unitsMiB / GiB / KiB को सिर्फ "B" में बदलने के लिए कह सकते हैं और इसे संभाल लेंगे, लेकिन आपको कुछ ऐसा करना होगा (यह मानते हुए कि आपका आउटपुट वर्जित है, अन्यथा cutउचित रूप से)

{your output} | cut -f1 '-d{tab}' | xargs -L 1 -I {} units -1t {}iB B | awk '{s+=$1}END{printf "%d\n",s}'

अच्छी तरह से उल्लेख किया है, कि परिशुद्धता का नुकसान है। इकाइयों को इनपुट सप्लीमेंट करने से भी काम चल जाता है .. लेकिन मैं unitsअपने न्यूनतम डिस्ट्रो पर गायब पाया गया! मुझे लगता है कि अगर हम सब पर पूर्ण नियंत्रण रखते तो हम यह सब अलग तरह से करते।
सेम

2
VALUE=$1

for i in "g G m M k K"; do
        VALUE=${VALUE//[gG]/*1024m}
        VALUE=${VALUE//[mM]/*1024k}
        VALUE=${VALUE//[kK]/*1024}
done

[ ${VALUE//\*/} -gt 0 ] && echo VALUE=$((VALUE)) || echo "ERROR: size invalid, pls enter correct size"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.