বাশকে কীভাবে যুক্তিটি alচ্ছিক হিসাবে তৈরি করবেন?


13

9 টি যুক্তি সহ নীচে ফাংশন:

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

আমি পরেরগুলিতে দ্বিতীয় আর্গুমেন্টটি তৈরি করতে চাই (3.9) একটি alচ্ছিক আর্গুমেন্ট হয়ে উঠতে ।

আমি যখন 2 টি যুক্তি দিয়ে ফাংশনটি কল করি তখন আমার ত্রুটি হয়:

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

নোট বোল্ড : প্রথম আর্গুমেন্ট এবং দ্বিতীয় যুক্তি জোর যুক্তি এবং ফাংশনের জন্য alচ্ছিক নয়। আমি কেবল দ্বিতীয়টিতে আর্গুমেন্ট চাই alচ্ছিক এবং যখন আমি ফাংশনটি 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
নিফটি! আমি জানি মন্তব্যগুলি কৃতজ্ঞ প্রশংসা এবং ধন্যবাদ জন্য নয়, তবে এই সমাধানটি কেবল ... দুষ্ট! :-)
— zwets

17

কটাক্ষপাত আছে shiftঅপারেটর। এটি আর্গুমেন্ট 2 এবং এর আগে অবস্থান 1 এবং পরবর্তী দিকে স্থানান্তর করবে, আর্গুমেন্ট 1 ত্যাগ করবে।

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

4

আপনি একটি পুনরাবৃত্ত সংজ্ঞা ব্যবহার করতে পারেন যা যখন sumআর্গুমেন্ট ছাড়াই ডাকা হয় তখন শেষ হয় ates আমরা 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 ক্ষেত্রে এই ক্ষেত্রে প্যারামিটারের সংখ্যা দেয়।

লিনাক্স রেডহাট 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

0 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


খালি সাথে একই আউটপুট:

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 টিরও বেশি পাস করার জন্য আমাদের একদল আর্গুমেন্ট ব্যবহার করতে হবে যা আপনার উত্তরটির জন্য সঠিক for
— нιηসেস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.