मैं बैश स्क्रिप्ट में नंबर कैसे जोड़ सकता हूं?


566

मेरे पास यह बैश स्क्रिप्ट है और मुझे लाइन 16 में एक समस्या थी। मैं लाइन 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
मुझे लगता है कि आप निम्नलिखित उत्तर का उपयोग करके भी एक शून्य मान छापेंगे। वहाँ एक चाल है, उदाहरण के लिए प्रक्रिया सबस्टेशन, "संख्या के अंदर" के अंतिम मूल्य को "बाहर की संख्या" तक लाने के लिए।
स्कॉट चू

जवाबों:


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अस्तित्व में थे और पूर्णांक मान थे?
बोरिपाल

1
हाँ वे मौजूद हैं, लेकिन एक चर डबल है .. कि एक समस्या है ??
निक

2
हाँ, यह एक समस्या है :) नोट: $((..))अंकगणित मूल्यांकन बैश में निष्पादित किया जाता है। exprएक अलग प्रक्रिया के रूप में निष्पादित किया जाता है, इसलिए यह बहुत धीमा होने वाला है। सिस्टम पर बाद के एक का उपयोग करें जहाँ arithemtic मूल्यांकन समर्थित नहीं है (sh! = bash)
Karoly Horvath

4
चूंकि $((…))POSIX द्वारा मानकीकृत है, यह तेजी से दुर्लभ हो जाना चाहिए जो exprआवश्यक है।
chepner

115

$(( ))अंकगणित विस्तार का उपयोग करें ।

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

देखें अध्याय 13. अंकगणित विस्तार अधिक जानकारी के लिए।


2
अजीब। जब मैं गणना करने की कोशिश करता हूं तो यह यहां काम नहीं करता है 191.003 + 190
सिगुर

2
दशमलव बिंदु के साथ संख्याओं के लिए काम नहीं करता है।
fivedogit

30

इसे करने के एक हजार और एक तरीके हैं। यहां एक का उपयोग किया गया है dc(एक रिवर्स-पॉलिश डेस्क कैलकुलेटर जो असीमित सटीक अंकगणित का समर्थन करता है):

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

लेकिन अगर वह आपके लिए या (या पोर्टेबिलिटी के मामलों में) बाश-वाई है तो आप कह सकते हैं

echo $num1 $num2 + p | dc

लेकिन शायद आप उन लोगों में से एक हैं जो सोचते हैं कि आरपीएन icky और अजीब है; चिंता मत करो! 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 कमांड एक अंश लौटाता है, तो आप फिर से डिज़ाइन करना चाहेंगे: यहाँ आपके कोड ने 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

मैं सिंटैक्स को हमेशा भूल जाता हूं इसलिए मुझे Google पर आना होता है, लेकिन फिर मुझे वह नहीं मिल रहा है जिससे मैं परिचित हूं: P। यह मेरे लिए सबसे साफ है और अन्य भाषाओं में मुझे जो उम्मीद है, उससे अधिक सच है।

i=0
((i++))

echo $i;


15

मुझे वास्तव में यह तरीका पसंद है, कम अव्यवस्था:

count=$[count+1]

1
यह काम क्यों कर रहा है, वैसे? हम इसे कैसे कहते हैं? मुझे इनके बारे में डॉक्स नहीं मिल सकते हैं।
स्काईलाइन75489

4
कम अव्यवस्था, लेकिन पदावनत।
केमिली गौडेय्यून


7

एक और पोर्टेबल POSIXआज्ञाकारी तरीका है bash, जिसे सुविधा .bashrcके सभी अंकगणितीय ऑपरेटरों के लिए एक फ़ंक्शन के रूप में परिभाषित किया जा सकता है ।

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

और इसे कमांड-लाइन के रूप में कॉल करें,

addNumbers 1 2 3 4 5 100
115

विचार इनपुट-फील्ड-सेपरेटर (IFS) का bashउपयोग करने के लिए है , एक विशेष चर जिसका उपयोग विस्तार के बाद शब्द विभाजन के लिए और शब्दों में लाइनों को विभाजित करने के लिए किया जाता है। फ़ंक्शन स्थानीय रूप से शब्द संचालक के रूप में शब्द-विभाजन वर्ण का उपयोग करने के लिए मान बदलता है +

याद रखें कि IFSयह स्थानीय रूप से बदला गया है और फ़ंक्शन स्कोप के बाहर डिफ़ॉल्ट व्यवहार पर प्रभाव नहीं डालता IFSहै। man bashपृष्ठ का एक अंश ,

शेल IFS के प्रत्येक चरित्र को एक सीमांकक के रूप में मानता है, और इन वर्णों पर अन्य विस्तार के परिणामों को शब्दों में विभाजित करता है। यदि IFS परेशान है, या इसका मान ठीक है, डिफ़ॉल्ट है, तो पिछले विस्तार के परिणामों के आरंभ और अंत में, के अनुक्रमों को अनदेखा किया जाता है, और IFS वर्णों के किसी भी क्रम की शुरुआत या अंत में परिसीमन नहीं किया जाता है शब्दों।

"$(( $* ))"द्वारा विभाजन हो गया पारित कर दिया तर्कों की सूची का प्रतिनिधित्व करता है +और बाद में योग मान का उपयोग कर उत्पादन होता है 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

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