एक फ़ाइल में वैज्ञानिक संख्या की संख्या की गणना करने के लिए पर्ल का उपयोग करना


10

मैं एक फ़ाइल में वैज्ञानिक संख्याओं की संख्या कैसे गिन सकता हूं? फ़ाइल में हेडर की कुछ लाइनें भी होती हैं जिन्हें छोड़ना पड़ता है।

फ़ाइल की सामग्री का एक हिस्सा नीचे है।

FileHeaderLine1
FileHeaderLine2
FileHeaderLine3
FileHeaderLine4
2.91999996E-001 2.97030300E-001 3.02060604E-001 3.07090908E-001 3.12121212E-001 3.17151517E-001
3.22181821E-001 3.27212125E-001 3.32242429E-001 3.37272733E-001 3.42303038E-001 3.47333342E-001
3.52363646E-001 3.57393950E-001 3.62424254E-001 3.67454559E-001 3.72484863E-001 3.77515137E-001
3.82545441E-001 3.87575746E-001 3.92606050E-001 3.97636354E-001 4.02666658E-001 4.07696962E-001
4.12727267E-001 4.17757571E-001 4.22787875E-001 4.27818179E-001 4.32848483E-001 4.37878788E-001
4.42909092E-001 4.47939396E-001 4.52969700E-001

तो, मैं उपरोक्त उदाहरण की पहली चार पंक्तियों को कैसे छोड़ सकता हूं और फ़ाइल में वैज्ञानिक संख्याओं की संख्या गिन सकता हूं?

जवाबों:


14

कोर मॉड्यूल के साथ Scalar::Util, आप कर सकते हैं:

$ perl -MScalar::Util=looks_like_number -anle '
    $count += grep { looks_like_number($_) } @F;
    END { print $count }
' file
33

के बारे में अधिक looks_like_numberदेख सकते हैं perldoc perlapi


+1 शांत, मैं के बारे में नहीं पता थाlooks_like_number
steeldriver

7

GNU grep का उपयोग करना

आप grepऐसा करने के लिए PCRE सुविधाओं का उपयोग कर सकते हैं । संयोग से उसी पैटर्न का उपयोग पर्ल में भी किया जा सकता है:

$ grep -oP '\d+E[-+]?\d+' file.txt  | wc -l
33

आप wc -wशब्दों को गिनने के लिए भी उपयोग कर सकते हैं , मैं ऊपर की पंक्तियों को गिन रहा हूं, लेकिन grepएक पंक्ति में एक ही मैच देता है तो यह वास्तव में उस परिदृश्य में मायने नहीं रखता है।

पर्ल का उपयोग करना

पर्ल के लिए आप इस एक लाइनर का उपयोग कर सकते हैं:

$ perl -lane '$c += grep /\d+E[-+]?\d+/, @F; END { print $c; }' file.txt 
33

संदर्भ


@StephaneChazelas - संपादन के लिए धन्यवाद। क्षमा करें, मैं केवल कभी जीएनयू सिस्टम पर हूं इसलिए हर समय इस बिंदु को भूल जाते हैं। मैं उस गलती को न करने की कोशिश करूँगा।
स्लम

4

egrep काम करेगा:

egrep "[0-9].[0-9]E-[0-9]" YourFile | wc -w

अपडेट करें:

यदि एक पंक्ति में एक संख्या और कुछ अन्य स्ट्रिंग दोनों होते हैं, तो हम awkसमस्या को हल करने के लिए उपयोग कर सकते हैं :

awk -F' ' '{for(i=1;i<=NF;i++)if(!(i%1))$i=$i "\n"}1' YourFile | egrep "[0-9].[0-9]E-[0-9]" | wc -w ( or wc -l )

यह गलत परिणाम देगा यदि एक पंक्ति में एक संख्या और कुछ अन्य स्ट्रिंग दोनों होते हैं। ऊपर दिए गए उत्तर जो केवल मिलान के लिए grep -o विकल्प का उपयोग करता है, अधिक सही है।
जॉनी

मुझे -oPपहले slm उत्तर में दिए गए विकल्प के बारे में नहीं पता था , लेकिन मैंने awk@Johnny
Nidal

3

मान लें कि आपके पास 4 वीं पंक्ति के बाद केवल वैज्ञानिक संख्याएं हैं, तो आप नीचे कुछ ऐसा कर सकते हैं।

tail -n +5 filename | wc - w

आपके द्वारा प्रदत्त इनपुट के लिए, उपरोक्त कमांड को चलाने के बाद आउटपुट 33 है


3

यदि आपको बस पेरेल में हेडर लाइनों के बाद व्हाट्सएप सीमांकित फ़ील्ड की संख्या की गणना करने की आवश्यकता है , तो मुझे लगता है कि आप बस हो सकते हैं

perl -lane '$sum += $#F+1 if $. > 4; END{print $sum}' file

यदि आपको वास्तव में केवल वैज्ञानिक-स्वरूपित संख्याओं की गणना करने की आवश्यकता है, तो एक दृष्टिकोण उपयुक्त रेगेक्स के अनुसार संख्याओं को खोजने और बदलने के लिए हो सकता है और फिर प्रतिस्थापन की संख्या की गणना कर सकता है (जब आप इसे एक चर में बदल देते हैं, तो पर्ल प्रतिस्थापन प्रतिस्थापन की संख्या को वापस कर देता है। )

perl -lane '$sum += s/[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?//g if $. > 4; END{print $sum}' file

2

यह सब नीचे चला जाता है कि आप वास्तव में एक वैज्ञानिक संख्या पर विचार करना चाहते हैं , आप अपने इनपुट से क्या उम्मीद कर सकते हैं, और जहां आप इनपुट में उन नंबरों को खोजने के लिए स्वीकार कर सकते हैं।

उदाहरण के लिए, इसमें:

That's inferior to the LK2E2000 model.

मैं 0 या 2 (inf और 2E2000) या 3 (inf, 2E200, 0) नंबर (या चरम पर ले जाया गया), वर्णों के सभी अनुक्रमों की तलाश कर सकता हूं जो एक वैध संख्या बनाते हैं: 17 (inf, 2, 2E2, inf) 2E20, 2E200, 2E200, 2E2000, 2, 20, 200, 2000, 0, 00, 000, 0, 00, 0))।

यदि आप जानते हैं कि आपके इनपुट में X.XXXXXXXXE-XXX में केवल संख्याएँ हैं, और वे अपने स्वयं के शब्दों पर हैं, तो यह संपूर्ण शब्दों के लिए केवल देखने के लिए सुरक्षित हो सकता है:

tr -s '[[:blank:]]' '[\n*]' | LC_ALL=C grep -xEc '[0-9]\.[0-9]{8}E-[0-9]{3}'

वहाँ विचार, प्रति पंक्ति एक शब्द प्राप्त करना है और पूरी लाइन ( -x) को आपके इच्छित पैटर्न के साथ मिलान करना है। किसी भी scientify अंकन संख्या अनुमति देने के लिए (-1.2e + 1234 ... जब तक कि वहाँ एक है eया E), तो आप करने के लिए पैटर्न को बदल सकता है:

[-+]?([0-9]+\.[0-9]*|[0-9]*\.[0-9])[eE][-+]?[0-9]+

या e...दशमलव फ़्लोटिंग पॉइंट नंबरों की सभी प्रकार की अनुमति देने के लिए भाग को वैकल्पिक बनाएं :

[-+]?([0-9]+\.[0-9]*|[0-9]*\.[0-9])([eE][-+]?[0-9]+)?

यह सब आपके विशिष्ट इनपुट के लिए एक ही उत्तर देता है, लेकिन जहां इससे फर्क पड़ता है वह वह जगह है जहां आपके नमूने में दिखाए गए सख्त पैटर्न से प्रस्थान होता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.