বাশের সংখ্যার তুলনা করা


545

আমি বাশ টার্মিনালের জন্য স্ক্রিপ্টগুলি লেখার বিষয়ে শিখতে শুরু করি, তবে কীভাবে তুলনাগুলি সঠিকভাবে কাজ করা যায় সে বিষয়ে আমি কাজ করতে পারি না। আমি যে স্ক্রিপ্টটি ব্যবহার করছি তা হ'ল:

echo "enter two numbers";
read a b;

echo "a=$a";
echo "b=$b";

if [ $a \> $b ];
then 
    echo "a is greater than b";
else
    echo "b is greater than a";
fi;

সমস্যাটি হ'ল এটি প্রথম অঙ্ক থেকে সংখ্যাটি তুলনা করে, অর্থাৎ 9টি 10 ​​এর চেয়ে বড়, তবে 1 09 এর চেয়ে বড়।

সত্যের তুলনা করতে আমি কীভাবে সংখ্যাগুলিকে এক ধরণের রূপান্তর করতে পারি?


1
বেসিক পড়া: বাশফ্যাঙ্কা
লোপেজ

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

6
শীর্ষস্থানীয় শূন্যগুলির সাথে সংখ্যাগুলিকে দশমিকের দিকে বাধ্য করার জন্য: 10#$numberসুতরাং number=09; echo "$((10#$number))"আউটপুট হবে 9যখন echo $((number))একটি "বেসের জন্য খুব বড় মানের" ত্রুটি তৈরি করবে।
পরবর্তী বিজ্ঞপ্তি না দেওয়া পর্যন্ত বিরতি দেওয়া হয়েছে।

4
উত্তরগুলি সমস্ত কি আপনাকে সঠিক তা জানায় তবে কী ভুল তা নয়: >অপারেটর [কমান্ডটিতে যা করে তা হল দুটি সংখ্যাটি যে ক্রম অনুসারে সাজানো উচিত তার চেয়ে তুলনামূলকভাবে তারা সংখ্যা অনুসারে বাছাই করবে। আপনি আরও তথ্য খুঁজে পেতে পারেন man test
ব্যবহারকারী 3035772

উত্তর:


878

ব্যাশে আপনার গাণিতিক প্রসঙ্গে আপনার চেক করা উচিত :

if (( a > b )); then
    ...
fi

যে পসিক্স শেলগুলি সমর্থন করে না তাদের জন্য (())আপনি ব্যবহার করতে পারেন -ltএবং -gt

if [ "$a" -gt "$b" ]; then
    ...
fi

আপনি help testবা এর সাথে তুলনা অপারেটরগুলির একটি সম্পূর্ণ তালিকা পেতে পারেন man test


7
@ জোর্ডানমের দ্বারা যেমনটি "$a" -gt "$b"বলা হয়েছে সঠিক উত্তর। টেস্ট অপারেটর: টেস্ট কনস্ট্রাক্টস এর একটি ভাল তালিকা এখানে ।
জেফারি টমাস

এটি অবশ্যই কাজ করছে তবে আমি এখনও (": (09: বেসের জন্য খুব ভাল মানের (ত্রুটির টোকেন" 09 ")) পাচ্ছি তবে যদি আমি 1 এবং 09 এর তুলনা করি তবে 01 এবং 09 যা বিজোড় নয় তবে এটি মূলত সমাধান হয়েছে আমার সমস্যা তাই ধন্যবাদ!
2013

8
@ বিজ্ঞাপন2013 আপনার জিরো দিয়ে সংখ্যার উপসর্গ করা উচিত নয়। জিরো-পূর্বে সমাধান সংখ্যার ব্যাশ মধ্যে অকট্যাল হয়
Aleks-ড্যানিয়েল Jakimenko-এ।

8
সাবধান যে testএকটি প্রোগ্রাম হিসাবে [। সুতরাং help testযে সম্পর্কে তথ্য দেয়। অন্তর্নির্মিতগুলি ( [[এবং (() আপনার কী ব্যবহার করা উচিত তা সন্ধান করার জন্য help bashএবং সেই অংশটিতে নেভিগেট করতে হবে।
রেডএক্স

1
পাটিগণিতের এক্সপ্রেশন দুর্দান্ত তবে অপারেশনগুলিকে এক্সপ্রেশন হিসাবে বিবেচনা করা হয় ।
এক্স-ইয়ুরি

179

খুব সহজ

#!/bin/bash

a=2462620
b=2462620

if [ "$a" -eq "$b" ];then
  echo "They're equal";
fi

আপনি বাশ স্ক্রিপ্টিংয়ের দুর্দান্ত বিশ্বে আরও সংখ্যার তুলনা চাইলে আপনি এই চিটশিটটি পরীক্ষা করে দেখতে পারেন।

সংক্ষেপে, পূর্ণসংখ্যার সাথে কেবল তুলনা করা যেতে পারে:

-eq # equal
-ne # not equal
-lt # less than
-le # less than or equal
-gt # greater than
-ge # greater than or equal

আমি কেবল আপনার অন্যান্য পরিবর্তনটিকে অস্বীকার করেছি - চারদিকে ডাবল উদ্ধৃতি "$a"এবং "$b"কঠোরভাবে প্রয়োজনীয় নয় তবে সেগুলি অনুশীলন। কোঁকড়া ধনুর্বন্ধনী এখানে কার্যকর কিছু করতে পারে না।
টম ফেনেক

1
আপনি যে দুর্দান্ত চিটশিটটি যুক্ত করেছেন, এটি আগে খুঁজে পাননি - এখন বাশকে আর যাদু এবং অনাকাঙ্ক্ষিত বলে মনে হচ্ছে না - আপনাকে ধন্যবাদ!
ইলজা

উদ্ধৃতিগুলি "বাধ্যতামূলক বা [ $a -eq $b ]ঠিক আছে কি?
derHugo

@derHugo এর উদ্ধৃতিগুলি alচ্ছিক। গিলেজ যখন তাদের ব্যবহার করার জন্য এ আপনি আরো ভালো ব্যাখ্যা রয়েছে unix.stackexchange.com/a/68748/50394
ড্যানিয়েল আন্দ্রেই Mincă


38

এমন একটি দুর্দান্ত জিনিস রয়েছে যা সম্পর্কে কিছু লোক জানেন না:

echo $(( a < b ? a : b ))

এই কোডটি সবচেয়ে ছোট সংখ্যাটি মুদ্রণ করবে aএবং এর বাইরেb


5
এটা সত্যি না. এটি প্রিন্ট হবে bযদি a == b
কনসোলবাক্স

88
@ কনসোলবক্সটি কি কেবল আমি, বা ৫ এবং ৫ এর মধ্যে ক্ষুদ্রতম সংখ্যাটি 5?
আলেকস-ড্যানিয়েল জাকিমেনকো-এ।

4
আপনার বক্তব্য অস্পষ্ট। এমনকি এর মতো কোনও আদেশে আবেদন করাও এটি করবে না:echo "The smaller number is $(( a < b ? a : b ))."
কনসোলবক্স

4
তিনি যা বলছেন a < bতা এখনও সত্য যদি a == b। আমি বাশের শর্তসাপেক্ষে সমস্ত অস্পষ্টতা জানি না, তবে প্রায় অবশ্যই এমন পরিস্থিতি রয়েছে যেখানে এটি কোনও পার্থক্য আনবে।
বাইকমেলে

4
@ বাইকেমুলে না, সে তা বলছে না। যদি a == b, তবে a < bএটি মিথ্যাতে মূল্যায়ন করে, তাই এটি মুদ্রণ করবে b
পরিস্কারকারীরা

21

বাশে আমি এটি করা পছন্দ করি কারণ এটি (( ))গাণিতিক ক্রিয়াকলাপ হিসাবে নিজেকে আরও সম্বোধন করে যা ব্যবহার করে গাণিতিক বেশি।

[[ N -gt M ]]

যতক্ষণ না জটিল জিনিস পছন্দ করি

(( (N + 1) > M ))

তবে প্রত্যেকেরই নিজস্ব পছন্দ রয়েছে। দুঃখজনক বিষয় হ'ল কিছু লোক তাদের বেসরকারী মানদণ্ড চাপিয়ে দেয়।

হালনাগাদ:

আপনি আসলে এটি করতে পারেন:

[[ 'N + 1' -gt M ]]

যা আপনাকে [[ ]]পাটিগণিত সামগ্রীর পাশাপাশি অন্য কিছু করতে পারে add


3
এর থেকে বোঝা যাচ্ছে যে এটি [[ ]]একটি গাণিতিক প্রসঙ্গে জোর করে (( )), যেখানে Nএটির মতো আচরণ করা হয় $Nতবে আমি এটি সঠিক বলে মনে করি না। বা, যদি এটি উদ্দেশ্য না হয় তবে এর ব্যবহার Nএবং Mবিভ্রান্তিকর।
বেঞ্জামিন ডাব্লু।

@ বেনজামিন ডাব্লু। এটির জন্য চেটের কাছ থেকে নিশ্চিতকরণের প্রয়োজন হবে তবে -ইউইকে, -নে, -ল্ট, -লে, -জিটি, এবং -ge "গাণিতিক পরীক্ষা" (নথিভুক্ত) এর ফর্ম যা এটি বোঝাতে পারে যে অপারেশনগুলি পাটিগণিতের মত প্রকাশের সাপেক্ষে ভাল ..
কনসোলবক্স

এটিতে ফিরে আসার জন্য ধন্যবাদ, যেহেতু আপনি পুরোপুরি ঠিক আছেন এবং ম্যানুয়ালটি এটিকে পরিষ্কারভাবে বলেছে: " [[কমান্ডের সাথে ব্যবহার করার সময় , Arg1এবং Arg2গণিতিক এক্সপ্রেশন হিসাবে মূল্যায়ন করা হয় [...]"।
বেনিয়ামিন ডব্লিউ

আমার আছে NUMBER=0.0; while [[ "$NUMBER" -lt "1.0" ]]; doএবং এটি বলেছেbash: [[: 0.0: syntax error: invalid arithmetic operator (error token is ".0")
হারুন ফ্রাঙ্ক

অ্যারোনফ্রেঙ্ক বাশ পাটিগণিত দশমিকগুলি সমর্থন করে না।
কনসোলবক্স

6

এই কোডটিও ফ্লোটগুলির সাথে তুলনা করতে পারে। এটি awk ব্যবহার করছে (এটি খাঁটি বাশ নয়) তবে এটি কোনও সমস্যা হওয়া উচিত নয়, কারণ অ্যাডাব্লিক একটি স্ট্যান্ডার্ড পসিক্স কমান্ড যা সম্ভবত আপনার অপারেটিং সিস্টেমের মাধ্যমে ডিফল্টরূপে প্রেরণ করা হয়।

$ awk 'BEGIN {return_code=(-1.2345 == -1.2345) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
0
$ awk 'BEGIN {return_code=(-1.2345 >= -1.2345) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
0
$ awk 'BEGIN {return_code=(-1.2345 < -1.2345) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
1
$ awk 'BEGIN {return_code=(-1.2345 < 2) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
0
$ awk 'BEGIN {return_code=(-1.2345 > 2) ? 0 : 1; exit} END {exit return_code}'
$ echo $?

এটি ব্যবহারের জন্য আরও ছোট করার জন্য, এই ফাংশনটি ব্যবহার করুন:

compare_nums()
{
   # Function to compare two numbers (float or integers) by using awk.
   # The function will not print anything, but it will return 0 (if the comparison is true) or 1
   # (if the comparison is false) exit codes, so it can be used directly in shell one liners.
   #############
   ### Usage ###
   ### Note that you have to enclose the comparison operator in quotes.
   #############
   # compare_nums 1 ">" 2 # returns false
   # compare_nums 1.23 "<=" 2 # returns true
   # compare_nums -1.238 "<=" -2 # returns false
   #############################################
   num1=$1
   op=$2
   num2=$3
   E_BADARGS=65

   # Make sure that the provided numbers are actually numbers.
   if ! [[ $num1 =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then >&2 echo "$num1 is not a number"; return $E_BADARGS; fi
   if ! [[ $num2 =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then >&2 echo "$num2 is not a number"; return $E_BADARGS; fi

   # If you want to print the exit code as well (instead of only returning it), uncomment
   # the awk line below and comment the uncommented one which is two lines below.
   #awk 'BEGIN {print return_code=('$num1' '$op' '$num2') ? 0 : 1; exit} END {exit return_code}'
   awk 'BEGIN {return_code=('$num1' '$op' '$num2') ? 0 : 1; exit} END {exit return_code}'
   return_code=$?
   return $return_code
}

$ compare_nums -1.2345 ">=" -1.2345 && echo true || echo false
true
$ compare_nums -1.2345 ">=" 23 && echo true || echo false
false

1
আমি প্রচুর সংখ্যার সাথে কাজ করছি এবং bashতাদের সঠিকভাবে তুলনা করতে ব্যর্থ হয়েছি (চেষ্টা করুন if (( 18446744073692774399 < 8589934592 )); then echo 'integer overflow'; fi)। awkকবজ ( if awk "BEGIN {return_code=(18446744073692774399 > 8589934592) ? 0 : 1; exit} END {exit return_code}"; then echo 'no integer overflow'; fi) এর মতো কাজ করে ।
জৌমে

3

আপনার যদি ভাসমান থাকে তবে আপনি একটি ফাংশন লিখতে পারেন এবং তারপরে উদাহরণটি ব্যবহার করতে পারেন

#!/bin/bash

function float_gt() {
    perl -e "{if($1>$2){print 1} else {print 0}}"
}

x=3.14
y=5.20
if [ $(float_gt $x $y) == 1 ] ; then
    echo "do stuff with x"
else
    echo "do stuff with y"
fi

2

সংস্করণ স্ট্রিংকে তুলনামূলকভাবে সমান পূর্ণসংখ্যার মানগুলিতে রূপান্তর করতে আমি একটি ছোট ফাংশন ব্যবহার করে এটি সমাধান করেছি:

function versionToInt() {
  local IFS=.
  parts=($1)
  let val=1000000*parts[0]+1000*parts[1]+parts[2]
  echo $val
}

এটি দুটি গুরুত্বপূর্ণ অনুমান করে:

  1. ইনপুট একটি " সাধারণ সেমওয়ার স্ট্রিং "
  2. প্রতিটি অংশ 0-999 এর মধ্যে

উদাহরণ স্বরূপ

versionToInt 12.34.56  # --> 12034056
versionToInt 1.2.3     # -->  1002003

npmকমান্ড ন্যূনতম প্রয়োজনীয়তা পূরণ করে কিনা তা পরীক্ষা করে দেখার উদাহরণ ...

NPM_ACTUAL=$(versionToInt $(npm --version))  # Capture npm version
NPM_REQUIRED=$(versionToInt 4.3.0)           # Desired version
if [ $NPM_ACTUAL \< $NPM_REQUIRED ]; then
  echo "Please update to npm@latest"
  exit 1
fi

'সাজানো-ভি' দিয়ে আপনি সংস্করণ নম্বরগুলি বাছাই করতে পারেন এবং তারপরে কী করবেন তা সিদ্ধান্ত নিতে পারেন। আপনি এর তুলনামূলক ফাংশনটি লিখতে পারেন: ফাংশন ভার্সন_ল্ট () {পরীক্ষা "$ (প্রিন্টফ '% s \ n'" $ @ "| সাজানো-ভি | হেড -n 1)" == "$ 1"; } এবং এটি এর মতো ব্যবহার করুন: যদি version_lt $ v1 $ v2; তারপরে ...
কোয়েম

2

আপনি যদি ভাসা সংখ্যাও ব্যবহার করতে চান তবে ব্র্যাকেট স্টাফ (যেমন, [[ $a -gt $b ]]বা (( $a > $b ))) যথেষ্ট নয়; এটি একটি সিনট্যাক্স ত্রুটির প্রতিবেদন করবে। আপনি যদি পূর্ণসংখ্যার সাথে ফ্লোট নম্বর বা ফ্লোট নম্বর তুলনা করতে চান, আপনি ব্যবহার করতে পারেন (( $(bc <<< "...") ))

উদাহরণ স্বরূপ,

a=2.00
b=1

if (( $(bc <<<"$a > $b") )); then 
    echo "a is greater than b"
else
    echo "a is not greater than b"
fi

আপনি যদি বিবৃতিতে একাধিক তুলনা অন্তর্ভুক্ত করতে পারেন। উদাহরণ স্বরূপ,

a=2.
b=1
c=1.0000

if (( $(bc <<<"$b == $c && $b < $a") )); then 
    echo "b is equal to c but less than a"
else
    echo "b is either not equal to c and/or not less than a"
fi

আপনি যদি একটি সাংখ্যিক ভেরিয়েবল (পূর্ণসংখ্যা বা না) পরীক্ষা করতে চান তবে এটি সহায়ক।


এটি আমার পক্ষে কাজ করে না। আমি যতদূর বলতে পারি, বিসি কমান্ডটি একটি প্রস্থান মূল্য ফেরত দেয় না বরং তুলনাটি সত্য হলে ("অন্যথায়" 0 ")" 1 "মুদ্রণ করে। পরিবর্তে আমাকে এটি লিখতে হবে:if [ "$(bc <<<"$a > $b") == "1" ]; then echo "a is greater than b; fi
তেরজে মিকাল

@ তেরজেমিকাল আপনার কমান্ডের জন্য, আপনার মানে if [ $(bc <<<"$a > $b") == "1" ]; then echo "a is greater than b"; fi? (আমি মনে করি আপনার আদেশটি ভুলভাবে লেখা হয়েছিল)) যদি তাই হয় তবে এটিও কার্যকর হয়। বাশ ক্যালকুলেটর (বিসি) কমান্ড একটি বেসিক ক্যালকুলেটর কমান্ড। আরও কিছু ব্যবহারের উদাহরণ এখানে এবং এখানে পাওয়া যায় । আমি জানি না কেন আমার উদাহরণ কমান্ডটি আপনার পক্ষে কার্যকর হয়নি।
এলসি-ডেটাস্টিস্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.