আমি কীভাবে বাশ স্ক্রিপ্টে নম্বর যুক্ত করতে পারি?


566

আমার এই বাশ স্ক্রিপ্টটি আছে এবং আমার লাইন 16 এ সমস্যা হয়েছিল I আমি লাইন 15 এর পূর্ববর্তী ফলাফলটি কীভাবে নিতে পারি এবং এটি 16-এর লাইনে চলকটিতে যুক্ত করতে পারি?

#!/bin/bash

num=0
metab=0

for ((i=1; i<=2; i++)); do
    for j in `ls output-$i-*`; do
        echo "$j"

        metab=$(cat $j|grep EndBuffer|awk '{sum+=$2} END { print sum/120}') (line15)
        num= $num + $metab   (line16)
    done
    echo "$num"
 done

2
আমি মনে করি আপনি নীচের উত্তরগুলি ব্যবহার করে এমনকি একটি শূন্য মান মুদ্রণ করবেন। "অভ্যন্তরের num" এর চূড়ান্ত মানটিকে "বাইরের নাম্বারে" আনার জন্য একটি কৌশল রয়েছে, যেমন প্রক্রিয়া বিকল্পটি।
স্কট চু

উত্তর:


974

পূর্ণসংখ্যার জন্য :

  • পাটিগণিতের সম্প্রসারণ ব্যবহার করুন :$((EXPR))

    num=$((num1 + num2))
    num=$(($num1 + $num2))       # Also works
    num=$((num1 + 2 + 3))        # ...
    num=$[num1+num2]             # Old, deprecated arithmetic expression syntax
  • বাহ্যিক exprইউটিলিটি ব্যবহার করে । মনে রাখবেন এটি কেবল সত্যিকারের পুরানো সিস্টেমগুলির জন্য প্রয়োজন।

    num=`expr $num1 + $num2`     # Whitespace for expr is important

ভাসমান পয়েন্টের জন্য :

বাশ সরাসরি এটি সমর্থন করে না, তবে আপনি ব্যবহার করতে পারেন এমন বেশ কয়েকটি বাহ্যিক সরঞ্জাম রয়েছে:

num=$(awk "BEGIN {print $num1+$num2; exit}")
num=$(python -c "print $num1+$num2")
num=$(perl -e "print $num1+$num2")
num=$(echo $num1 + $num2 | bc)   # Whitespace for echo is important

আপনি বৈজ্ঞানিক স্বরলিপিও ব্যবহার করতে পারেন (উদাহরণস্বরূপ, 2.5e+2)।


সাধারণ ক্ষতি :

  • কোনও ভেরিয়েবল সেট করার সময়, আপনার উভয় পাশেই সাদা স্থান থাকতে পারে না =, অন্যথায় এটি শেলটিকে প্রথমে শব্দের সাথে অ্যাপ্লিকেশনটির নাম হিসাবে চালিত করতে বাধ্য করবে (উদাহরণস্বরূপ, num=বা num)

    num= 1 num =2

  • bcএবং exprপ্রতিটি সংখ্যা এবং অপারেটরকে একটি পৃথক যুক্তি হিসাবে প্রত্যাশা করুন, তাই হোয়াইটস্পেস গুরুত্বপূর্ণ। তারা মত যুক্তি প্রক্রিয়া করতে পারবেন না 3+ +4

    num=`expr $num1+ $num2`


1
প্রথম উত্তরে এটি আমাকে এক্সপ্রেস করে: অ-সংখ্যাসূচক যুক্তি দ্বিতীয়টি কাজ করে না ..
নিক

1
@ নিক: ভেরিয়েবলের নামকরণ num1এবং num2অস্তিত্ব থাকা এবং পূর্ণসংখ্যার মান থাকা অবস্থায় আপনি কি এটি চেষ্টা করেছিলেন?
sorpigal

1
হ্যাঁ তারা বিদ্যমান আছে তবে একটি পরিবর্তনশীল দ্বিগুণ .. এটি কি সমস্যা ??
নিক

2
হ্যাঁ, এটি একটি সমস্যা :) দ্রষ্টব্য: $((..))পাটিগণিত মূল্যায়ন বাশ এ কার্যকর করা হয়। exprএকটি পৃথক প্রক্রিয়া হিসাবে কার্যকর করা হয়, তাই এটি অনেক ধীর হতে চলেছে। যেখানে arithemtic মূল্যায়ন সমর্থিত নয় সিস্টেমে পরেরটির একটি ব্যবহার (! SH = ব্যাশ)
Karoly Horvath

4
যেহেতু $((…))পসিক্স দ্বারা প্রমিতকরণ করা হয়েছে, এটি exprপ্রয়োজনীয় যা ক্রমশ বিরল হয়ে উঠতে হবে ।
চিপনার

115

$(( ))পাটিগণিতের সম্প্রসারণ ব্যবহার করুন ।

num=$(( $num + $metab ))

অধ্যায় 13 দেখুন। গাণিতিক সম্প্রসারণ আরও তথ্যের জন্য।


2
স্ট্রেঞ্জ। আমি যখন গণনা করার চেষ্টা করি তখন এটি কাজ করে না 191.003 + 190
সিগুর

2
দশমিক পয়েন্ট সহ সংখ্যার জন্য কাজ করে না।
পাঁচডোগিট

30

এটি করার এক হাজার এবং একটি উপায় রয়েছে। এখানে একটি ব্যবহার করছে dc(একটি বিপরীত-পোলিশ ডেস্ক ক্যালকুলেটর যা সীমাহীন নির্ভুল গণিত সমর্থন করে):

dc <<<"$num1 $num2 + p"

তবে যদি এটি আপনার পক্ষে খুব বেশি বাশ-ওয়াই হয় (বা বহনযোগ্যতার বিষয়গুলি) আপনি বলতে পারেন

echo $num1 $num2 + p | dc

তবে সম্ভবত আপনি সেই সমস্ত লোকদের মধ্যে যারা आरপিএনকে অদ্ভুত এবং অদ্ভুত বলে মনে করেন; চিন্তা করবেন না! bcআপনার জন্য এখানে:

bc <<< "$num1 + $num2"
echo $num1 + $num2 | bc

এটি বলেছিল, আপনার স্ক্রিপ্টে কিছু অপ্রাসঙ্গিক উন্নতি করা যেতে পারে:

#!/bin/bash

num=0
metab=0

for ((i=1; i<=2; i++)); do
    for j in output-$i-* ; do # 'for' can glob directly, no need to ls
            echo "$j"

             # 'grep' can read files, no need to use 'cat'
            metab=$(grep EndBuffer "$j" | awk '{sum+=$2} END { print sum/120}')
            num=$(( $num + $metab ))
    done
    echo "$num"
done

বাশ এফএকিউ 022 তে বর্ণিত হিসাবে , বাশ স্থানীয়ভাবে ভাসমান পয়েন্ট সংখ্যা সমর্থন করে না। আপনার যদি ভাসমান পয়েন্ট সংখ্যাগুলি যোগ করতে হয় তবে একটি বাহ্যিক সরঞ্জাম (যেমন bcবা dc) এর ব্যবহার প্রয়োজন।

এই ক্ষেত্রে সমাধান হবে

num=$(dc <<<"$num $metab + p")

সম্ভাব্য-ভাসমান-পয়েন্ট সংখ্যাগুলিকে এতে যোগ করতে num


1
@ সরপিগাল অনেক ধন্যবাদ ... আমি কি আপনাকে অন্য কিছু জিজ্ঞাসা করতে পারি..আমি কীভাবে প্রিন্ট করতে পারব না নাম্বার নয় তবে নাম্বার / 10 ??
নিক

23

ব্যাশে,

 num=5
 x=6
 (( num += x ))
 echo $num   # ==> 11

নোট করুন যে বাশ কেবলমাত্র পূর্ণসংখ্যার গাণিতিক পরিচালনা করতে পারে, সুতরাং যদি আপনার awk কমান্ড কোনও ভগ্নাংশ ফিরে আসে, তবে আপনি আবার ডিজাইন করতে চাইবেন: আপনার কোডটি কিছুটা গণিত করতে কিছুটা আবার লিখতে হবে।

num=0
for ((i=1; i<=2; i++)); do      
    for j in output-$i-*; do
        echo "$j"
        num=$(
           awk -v n="$num" '
               /EndBuffer/ {sum += $2}
               END {print n + (sum/120)}
           ' "$j"
        )
    done
    echo "$num"
done

20

আমি সিন্টেক্সটি সর্বদা ভুলে যাই তাই আমি গুগলে আসি, তবে তার সাথে আমি পরিচিত কখনও পাই না: পি। এটি আমার কাছে সবচেয়ে পরিষ্কার এবং আমি অন্যান্য ভাষায় যা আশা করব তার থেকে বেশি সত্য।

i=0
((i++))

echo $i;


15

আমি এই পদ্ধতিটিও খুব পছন্দ করি, কম বিশৃঙ্খলা:

count=$[count+1]

1
কেন এটি কাজ করছে? আমরা এটিকে কীভাবে ডাকব? আমি এগুলি সম্পর্কে ডক্স পাচ্ছি না।
skyline75489

4
কম বিশৃঙ্খলা থাকলেও হ্রাস করা হয়নি।
ক্যামিল গৌডেসুন 21


7

আরও একটি পোর্টেবল POSIXকমপ্লায়েন্ট উপায় bash, যা .bashrcসুবিধার সমস্ত পাটিগণিত অপারেটরের জন্য একটি ফাংশন হিসাবে সংজ্ঞায়িত করা যেতে পারে ।

addNumbers () {
    local IFS='+'
    printf "%s\n" "$(( $* ))"
}

এবং কেবল কমান্ড-লাইনে এটি হিসাবে কল করুন,

addNumbers 1 2 3 4 5 100
115

ধারণাটি হ'ল ইনপুট-ফিল্ড-সেপারেটর (আইএফএস) , যা bashবিস্তারের পরে শব্দ বিভাজনের জন্য ব্যবহৃত একটি বিশেষ পরিবর্তনশীল এবং লাইনগুলিকে শব্দের মধ্যে বিভক্ত করার জন্য ব্যবহৃত হয়। ফাংশনটি স্থানীয়ভাবে মানটিকে পরিবর্তিত করে যোগফল হিসাবে শব্দ বিভাজনকারী চরিত্রটি ব্যবহার করে +

মনে রাখবেন IFSস্থানীয়ভাবে পরিবর্তিত হয় এবং নেই না ডিফল্ট প্রভাবী IFSফাংশন আওতার বাইরে আচরণ। man bashপৃষ্ঠাটি থেকে একটি অংশ ,

শেলটি আইএফএসের প্রতিটি চরিত্রকে একটি সীমানার হিসাবে বিবেচনা করে এবং অন্যান্য বিস্তারের ফলাফলগুলিকে এই অক্ষরগুলির শব্দের মধ্যে বিভক্ত করে। যদি আইএফএসটি সেট না করা থাকে, বা এর মান ঠিক হয়, পূর্ববর্তী বিস্তারের ফলাফলের শুরু এবং শেষে, অগ্রাহ্য করা হয়, এবং এর পরে বা শেষে অগ্রাহ্য করা হয় এবং আইএফএস অক্ষরগুলির যে কোনও ক্রম শুরু বা শেষের দিকে সীমাবদ্ধ করে দেয় ves শব্দ।

দ্বারা "$(( $* ))"বিভক্ত হতে দেওয়া আর্গুমেন্টের তালিকা উপস্থাপন করে +এবং পরে যোগফলটি printfফাংশনটি ব্যবহার করে আউটপুট হয়। অন্যান্য গাণিতিক ক্রিয়াকলাপগুলিতেও সুযোগ বাড়ানোর জন্য ফাংশনটি বাড়ানো যেতে পারে।


2
#!/bin/bash

num=0
metab=0

for ((i=1; i<=2; i++)); do      
    for j in `ls output-$i-*`; do
        echo "$j"

        metab=$(cat $j|grep EndBuffer|awk '{sum+=$2} END { print sum/120}') (line15)
        let num=num+metab (line 16)
    done
    echo "$num"
done

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