सवाल बैश में एक चर कैसे बढ़ाया जाए?


मैंने दोनों का उपयोग करके एक संख्यात्मक चर बढ़ाने की कोशिश की है var=$var+1 तथा var=($var+1) बिना सफलता के। चर एक संख्या है, हालांकि बाश इसे स्ट्रिंग के रूप में पढ़ रहा है।

बश संस्करण 4.2.45 (1) - कृपया (x86_64-pc-linux-gnu) उबंटू 13.10 पर।


455
2017-12-03 16:34


मूल




जवाब:


बैश में एक चर को बढ़ाने के लिए एक से अधिक तरीके हैं, लेकिन आपने जो भी कोशिश की वह सही नहीं है।

आप उदाहरण के लिए उपयोग कर सकते हैं अंकगणितीय विस्तार:

var=$((var+1))
((var=var+1))
((var+=1))
((var++))

या आप उपयोग कर सकते हैं let:

let "var=var+1"
let "var+=1"
let "var++"

यह भी देखें: http://tldp.org/LDP/abs/html/dblparens.html


722
2017-12-03 16:39



या ((++var)) या ((var=var+1)) या ((var+=1))। - gniourf_gniourf
या var = $ (expr $ var + 1) - Javier López
मजे की बात है, var=0; ((var++)) जबकि एक त्रुटि कोड देता है var=0; ((var++)); ((var++)) नहीं करता। कोई विचार क्यों? - phunehehe
@phunehehe देखो help '(('। अंतिम पंक्ति कहती है: Returns 1 if EXPRESSION evaluates to 0; returns 0 otherwise. - Radu Rădeanu
क्या यह उपयोग करने के लिए सुरक्षित है let var++, बिना उद्धरण? - wjandrea


var=$((var + 1))

बैश उपयोग में अंकगणित $((...)) वाक्य - विन्यास।


101
2017-12-03 16:38



स्वीकृत उत्तर से काफी बेहतर है। केवल 10% अधिक जगह में, आप पर्याप्त उदाहरण प्रदान करने में कामयाब रहे (एक बहुत है - नौ उस बिंदु पर अधिक है जब आप बस दिखा रहे हैं), और आपने हमें यह जानने के लिए पर्याप्त जानकारी प्रदान की ((...))बैश में अंकगणित का उपयोग करने की कुंजी है। मुझे एहसास नहीं हुआ कि केवल स्वीकार्य उत्तर को देखते हुए - मैंने सोचा था कि संचालन के आदेश के बारे में नियमों का एक अजीब सेट था या स्वीकार्य उत्तर में सभी कोष्ठक के लिए अग्रणी कुछ था। - ArtOfWarfare


विभिन्न विकल्पों का प्रदर्शन विश्लेषण

करने के लिए धन्यवाद राडू रादेनु का जवाब जो बैश में एक चर को बढ़ाने के लिए निम्न तरीके प्रदान करता है:

var=$((var+1))
((var=var+1))
((var+=1))
((var++))
let "var=var+1"
let "var+=1" 
let "var++"

अन्य तरीके भी हैं। उदाहरण के लिए, इस प्रश्न के अन्य उत्तरों को देखें।

let var++
var=$((var++))
((++var))
{
    declare -i var
    var=var+1
    var+=1
}
{
    i=0
    i=$(expr $i + 1)
}

इतने सारे विकल्प होने से इन दो सवालों का कारण बनता है:

  1. क्या उनके बीच कोई प्रदर्शन अंतर है?
  2. यदि ऐसा है, जो सबसे अच्छा प्रदर्शन करता है?

वृद्धिशील प्रदर्शन परीक्षण कोड:

#!/bin/bash

# To focus exclusively on the performance of each type of increment
# statement, we should exclude bash performing while loops from the
# performance measure. So, let's time individual scripts that
# increment $i in their own unique way.

# Declare i as an integer for tests 12 and 13.
echo > t12 'declare -i i; i=i+1'
echo > t13 'declare -i i; i+=1'
# Set i for test 14.
echo > t14 'i=0; i=$(expr $i + 1)'

x=100000
while ((x--)); do
    echo >> t0 'i=$((i+1))'
    echo >> t1 'i=$((i++))'
    echo >> t2 '((i=i+1))'
    echo >> t3 '((i+=1))'
    echo >> t4 '((i++))'
    echo >> t5 '((++i))'
    echo >> t6 'let "i=i+1"'
    echo >> t7 'let "i+=1"'
    echo >> t8 'let "i++"'
    echo >> t9 'let i=i+1'
    echo >> t10 'let i+=1'
    echo >> t11 'let i++'
    echo >> t12 'i=i+1'
    echo >> t13 'i+=1'
    echo >> t14 'i=$(expr $i + 1)'
done

for script in t0 t1 t2 t3 t4 t5 t6 t7 t8 t9 t10 t11 t12 t13 t14; do
    line1="$(head -1 "$script")"
    printf "%-24s" "$line1"
    { time bash "$script"; } |& grep user
    # Since stderr is being piped to grep above, this will confirm
    # there are no errors from running the command:
    eval "$line1"
    rm "$script"
done

परिणाम:

i=$((i+1))              user    0m0.992s
i=$((i++))              user    0m0.964s
((i=i+1))               user    0m0.760s
((i+=1))                user    0m0.700s
((i++))                 user    0m0.644s
((++i))                 user    0m0.556s
let "i=i+1"             user    0m1.116s
let "i+=1"              user    0m1.100s
let "i++"               user    0m1.008s
let i=i+1               user    0m0.952s
let i+=1                user    0m1.040s
let i++                 user    0m0.820s
declare -i i; i=i+1     user    0m0.528s
declare -i i; i+=1      user    0m0.492s
i=0; i=$(expr $i + 1)   user    0m5.464s

निष्कर्ष:

ऐसा लगता है कि प्रदर्शन करने में बैश सबसे तेज़ है i+=1 कब $i एक पूर्णांक के रूप में घोषित किया गया है। let बयान विशेष रूप से धीमा लगता है, और expr अब तक सबसे धीमा है क्योंकि यह एक अंतर्निहित नहीं है।


62
2017-07-31 17:15



स्पष्ट रूप से गति कमांड लंबाई के साथ सहसंबंधित करता है। मुझे आश्चर्य है कि आदेश एक ही कार्य कहते हैं। - MatthewRock
i=(expr ...) एक वाक्यविन्यास त्रुटि है। क्या आपका मतलब है i=$(expr ...)? - muru
@मुरु फिक्स्ड, और लूप के लिए एक चेक जोड़ा। - wjandrea


यह भी है:

var=`expr $var + 1`

रिक्त स्थान और सावधानीपूर्वक ध्यान दें ` नहीं है '

जबकि राडू के जवाब, और टिप्पणियां, संपूर्ण और बहुत उपयोगी हैं, वे बाश-विशिष्ट हैं। मुझे पता है कि आपने विशेष रूप से बैश के बारे में पूछा था, लेकिन मैंने सोचा था कि जब मैं यूसीएलिनक्स के तहत व्यस्त बॉक्स में sh का उपयोग करके वही काम करना चाहता था, तो मुझे यह सवाल मिला क्योंकि मैं पाइप करूँगा। यह पोर्टेबल बैश से परे है।


14
2017-08-22 23:11



आप भी उपयोग कर सकते हैं i=$((i+1)) - wjandrea
अगर प्रक्रिया प्रतिस्थापन $(...) इस खोल पर उपलब्ध है, मैं इसके बजाय इसका उपयोग करने की सिफारिश करता हूं। - Radon Rosborough


यदि आप घोषणा करते हैं $var एक पूर्णांक के रूप में, फिर आपने पहली बार क्या प्रयास किया वास्तव में काम करेगा:

$ declare -i var=5
$ echo $var
5
$ var=$var+1
$ echo $var
6

संदर्भ: चर के प्रकार, शुरुआती के लिए बैश गाइड


9
2017-12-06 22:19





सभी उत्तरों में एक विधि गायब है - bc

$ VAR=7    
$ bc <<< "$VAR+2"
9
$ echo $VAR
7
$ VAR=$( bc <<< "$VAR+1" )
$ echo $VAR
8

bc द्वारा निर्दिष्ट है POSIX मानक, तो उबंटू और पॉज़िक्स-अनुपालन प्रणालियों के सभी संस्करणों पर मौजूद होना चाहिए। <<< पुनर्निर्देशन में बदला जा सकता है echo "$VAR" | bc पोर्टेबिलिटी के लिए, लेकिन चूंकि सवाल पूछता है bash - बस उपयोग करना ठीक है <<<


6
2018-02-23 13:58





वापसी कोड 1 मुद्दा सभी डिफ़ॉल्ट रूपों के लिए मौजूद है (let, (()), आदि।)। यह अक्सर परेशानी का कारण बनता है, उदाहरण के लिए, उपयोग की जाने वाली स्क्रिप्ट में set -o errexit। यहां त्रुटि कोड को रोकने के लिए मैं उपयोग कर रहा हूं 1 गणित अभिव्यक्तियों से मूल्यांकन करने के लिए 0;

math() { (( "$@" )) || true; }

math a = 10, b = 10
math a++, b+=2
math c = a + b
math mod = c % 20
echo $a $b $c $mod
#11 12 23 3

4