পার্ল ব্যবহার করে একটি ফাইলে বৈজ্ঞানিক সংখ্যার সংখ্যা গণনা করতে


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
স্টিল্ড্রাইভার

7

জিএনইউ গ্রেপ ব্যবহার করা হচ্ছে

আপনি grepপিসিআরই সুবিধা ব্যবহার করে এটি করতে পারেন । ঘটনাক্রমে পার্লেও একই প্যাটার্ন ব্যবহার করা যেতে পারে:

$ 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

তথ্যসূত্র


@ স্টাফেনচাজেলাস - সম্পাদনার জন্য ধন্যবাদ thanks দুঃখিত আমি কেবল জিএনইউ সিস্টেমে থাকি তাই এই পয়েন্টটি সর্বদা ভুলে যাবেন না। আমি সেই ভুলটি না করার চেষ্টা করব।
slm

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 )

যদি কোনও লাইনে একটি সংখ্যা এবং কিছু অন্যান্য স্ট্রিং উভয়ই থাকে তবে এটি ভুল ফলাফল দেয়। উপরের উত্তরটি কেবলমাত্র ম্যাচগুলি আউটপুট দেওয়ার জন্য গ্রেপের -ও বিকল্প ব্যবহার করে যা আরও সঠিক।
জনি

আমি -oPআগে এসএমএল উত্তরে উল্লিখিত বিকল্প সম্পর্কে জানতাম না , তবে আমি awk@ জন্নি ব্যবহার করে আমার সমস্যাটি সমাধান করেছি
নিদাল

3

ধরে নিলাম আপনার চতুর্থ লাইনের পরে বৈজ্ঞানিক সংখ্যা রয়েছে, আপনি নীচের মতো কিছু করতে পারেন।

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 (ইনফ এবং 2E2000) বা 3 (ইনফ, 2E200, 0) সংখ্যা খুঁজে পেতে পারি (বা চূড়ান্ত দিকে নিয়েছি, একটি বৈধ সংখ্যা গঠন করে এমন সমস্ত অক্ষরের সিকোয়েন্স খুঁজছি: 17 (ইনফ, 2, 2E2, 2E20, 2E200, 2E200, 2E2000, 2, 20, 200, 2000, 0, 00, 000, 0, 00, 0))।

আপনি যদি জানেন যে আপনার ইনপুটটির কেবলমাত্র এক্স.এক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্সএক্স সংখ্যা রয়েছে এবং সেগুলি তাদের নিজস্ব কথায় রয়েছে তবে পুরো শব্দে কেবল এটির জন্য এটি অনুসন্ধান করা নিরাপদ হতে পারে:

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

সেখানে ধারণাটি হ'ল প্রতি লাইনে একটি শব্দ পাওয়া এবং আপনি -xযে প্যাটার্নটি চান তার বিপরীতে পুরো লাইনটি মেলে । যেকোনও বৈজ্ঞানিক স্বরলিপি নম্বর (-1.2e + 1234 ... যতক্ষণ না একটি eবা সেখানে রয়েছে E) এর অনুমতি দেওয়ার জন্য, আপনি এই প্যাটার্নটি এতে পরিবর্তন করতে পারেন:

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

বা e...সব ধরণের দশমিক ভাসমান পয়েন্ট সংখ্যাগুলির অনুমতি দিতে অংশটি alচ্ছিক করুন:

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

এটি সমস্তই আপনার নির্দিষ্ট ইনপুটটির জন্য একই উত্তর দেয়, তবে যেখানে কোনও পার্থক্য হবে সেখানে আপনার ইনপুট রয়েছে যা আপনার নমুনায় প্রদর্শিত কঠোর নিদর্শন থেকে প্রস্থান করবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.