बैश में तर्क को वैकल्पिक कैसे बनाएं?


13

नीचे 9 तर्कों के साथ कार्य:

SUM() { 
    echo "The sum is $(($1+$2+$3+$4+$5+$6+$7+$8+$9))"
}

मैं अगले तर्क (3..9) को एक वैकल्पिक तर्क बनाना चाहता हूं ।

जब मैं समारोह में 2 तर्क देता हूं तो मुझे त्रुटि मिलती है:

SUM 3 8
bash: 3+8+++++++: syntax error: operand expected (error token is "+")

नोट बोल्ड : पहला तर्क और दूसरा तर्क बल तर्क हैं और फ़ंक्शन के लिए वैकल्पिक नहीं हैं। मैं केवल दूसरा तर्क चाहता हूं कि अगला वैकल्पिक हो और जब मैं फ़ंक्शन को 2 से कम कहता हूं तो फ़ंक्शन को कोई परिणाम नहीं लौटना चाहिए।

जवाबों:


22

यदि आप रिक्त स्थान के साथ तर्क पारित नहीं करेंगे:

sum() {  
[[ -n $2 ]] && echo $(( $(tr ' ' '+' <<<"$@") ))
}

प्रभाव:

$ sum 1 2 3
6

स्पष्टीकरण:

  1. <<<"some string"केवल "some string"इनपुट के रूप में फ़ीड करता है । इसके लिए शॉर्टहैंड के रूप में सोचें echo "some string" |। इसे हियर स्ट्रिंग कहा जाता है ।
  2. "$@"रिक्त स्थान द्वारा अलग किए गए सभी स्थितिगत मापदंडों में फैलता है। के बराबर है "$1 $2 ..."
  3. इसलिए, tr ' ' '+' <<<"$@"आउटपुट "$1+$2+$3...", जिसका मूल्यांकन बाहरी द्वारा किया जाता है $(( ))
  4. [[ -n $2 ]]परीक्षण यदि दूसरा पैरामीटर गैर-रिक्त है। आप के [[ -n $2 ]] &&साथ बदल सकता है [[ -z $2 ]] ||

दूसरा रास्ता:

sum() {
[[ -n $2 ]] && (IFS=+; echo $(( $* )))
}

स्पष्टीकरण:

  1. $*सिर्फ ऐसा है $@, सिवाय इसके कि पैरामीटर रिक्त स्थान से अलग नहीं होते हैं, लेकिन आंतरिक क्षेत्र विभाजक ( IFS) के पहले चरित्र द्वारा । इसके साथ IFS=+, यह "$ 1 + $ 2 + ..." तक फैलता है। देखें कि $ * और $ @ के बीच क्या अंतर है?
  2. हम IFSएक सबशेल में सेट होते हैं (आसपास के कोष्ठकों पर ध्यान दें) ताकि मुख्य शेल प्रभावित न हो। IFSडिफ़ॉल्ट रूप से है: \t\n(स्पेस, टैब, न्यूलाइन)। यह localचर का उपयोग करने का एक विकल्प है ।

अब आपके प्रश्न का उत्तर देने के लिए:

आप किसी भी चर या पैरामीटर के लिए एक डिफ़ॉल्ट मान का उपयोग कर सकते हैं । कोई एक:

SUM() { 
 echo "The sum is $(($1+$2+${3:-0}+${4:-0}+${5:-0}+${6:-0}+${7:-0}+${8:-0}+${9:-0}))" || false
}

या:

SUM() { 
 echo "The sum is $(($1+$2+${3:=0}+${4:=0}+${5:=0}+${6:=0}+${7:=0}+${8:=0}+${9:=0}))" || false
}

6
निफ्टी! मुझे पता है कि टिप्पणियां गंभीर प्रशंसा और धन्यवाद के लिए नहीं हैं, लेकिन यह समाधान सिर्फ है ... दुष्ट! :-)
8

17

shiftऑपरेटर पर एक नजर है । यह तर्क 2 और उसके बाद के पदों 1 और उसके बाद, तर्क 1 को छोड़ देगा।

sum () {
    local total=0;
    while [ $# -gt 0 ]; do
        total=$(($total + $1))
        shift
    done
    echo $total
}

4

आप एक पुनरावर्ती परिभाषा का उपयोग कर सकते हैं जो sumबिना तर्क के लागू होने पर समाप्त हो जाती है। हम इस तथ्य का उपयोग करते हैं कि testबिना तर्क के मूल्यांकन होता है false

sum () {
    test $1 && echo $(( $1 + $(shift; sum $@) )) || echo 0
}

3

इसे इस्तेमाल करे:

SUM () {
 [ $# -lt "2" ] && return 1
 for par in $@; do
   local sum=`expr $sum + $par`
 done
 echo $sum
 return 0
}

SUM 3 4 5
SUM 3 4 5 1 1 1 1 2 3 4 5

यह 12 और 30 को आउटपुट देगा।

$@पैरामीटर को संदर्भित करता है, पैरामीटर $#की संख्या लौटाता है, इस मामले में 3 या 11।

Linux redhat 4 पर परीक्षण किया गया


2

आप बस एक छोटे से लूप का उपयोग कर सकते हैं:

sum(){
    t=0;
    for i in "$@"; do t=$((t + i )); done
    echo $t;
}

हालांकि व्यक्तिगत रूप से, मैं सिर्फ perlया awkइसके बजाय का उपयोग करेंगे :

sum(){
 echo "$@" | perl -lane '$s+=$_ for @F; print $s'
}

या

sum(){
 echo "$@" | awk '{for(i=1; i<=NF; i++){k+=$i} print k}'
}

2

$ 1 से $ 9 के लिए 0 के रूप में डिफ़ॉल्ट मानों का उपयोग करें:

SUM() { 
    echo "The sum is $((${1:-0}+${2:-0}+${3:-0}+${4:-0}+${5:-0}+${6:-0}+${7:-0}+${8:-0}+${9:-0}))"
}

से man bash:

${parameter:-word}
    Use Default Values. If parameter is unset or null, the expansion
    of word is substituted. Otherwise, the value of parameter is
    substituted.

उदाहरण:

$ SUM

योग 0 है

$ SUM 1 2 

योग 3 है

$ SUM 1 1 1 1 1 1 1 1 1 

योग 9 है


Awk के साथ एक ही उत्पादन:

SUM() {
  echo -e ${@/%/\\n} | awk '{s+=$1} END {print "The sum is " s}'
}

1

यह मेरा अपना समाधान भी है जिसे मैंने आजमाया और पाया:

SUM() { 
    echo "The sum is $(($1+$2+$[$3]+$[$4]+$[$5]+$[$6]+$[$7]+$[$8]+$[$9]))"
 }

$ SUM 4 6 5
The sum is 15

लेकिन @ मूरू का जवाब अच्छा है।


+1: शून्य में खाली मापदंडों का मूल्यांकन करने के लिए दो अंकगणितीय विस्तार का दिलचस्प उपयोग ।
मुरहू

1
@ धन्यवाद, लेकिन इस मामले में मेरे जवाब में हम 9 से अधिक तर्कों का उपयोग नहीं करते हैं और हमें 9 से अधिक पास करने के लिए तर्कों के समूह का उपयोग करना होगा। आपके उत्तर के लिए धन्यवाद जो एकदम सही है।
α atsнιη
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.