আমি একটি শেল স্ক্রিপ্টে দুটি ভাসমান পয়েন্ট সংখ্যা তুলনা করতে চাই। নিম্নলিখিত কোডটি কাজ করছে না:
#!/bin/bash
min=12.45
val=10.35
if (( $val < $min )) ; then
min=$val
fi
echo $min
আমি একটি শেল স্ক্রিপ্টে দুটি ভাসমান পয়েন্ট সংখ্যা তুলনা করতে চাই। নিম্নলিখিত কোডটি কাজ করছে না:
#!/bin/bash
min=12.45
val=10.35
if (( $val < $min )) ; then
min=$val
fi
echo $min
উত্তর:
আপনি আলাদাভাবে পূর্ণসংখ্যা এবং ভগ্নাংশ অংশগুলি পরীক্ষা করতে পারেন:
#!/bin/bash
min=12.45
val=12.35
if (( ${val%%.*} < ${min%%.*} || ( ${val%%.*} == ${min%%.*} && ${val##*.} < ${min##*.} ) )) ; then
min=$val
fi
echo $min
ফেড মন্তব্যগুলিতে যেমন বলেছেন, এটি কেবল তখনই কাজ করে যদি উভয় সংখ্যার ভগ্নাংশের অংশ থাকে এবং উভয় ভগ্নাংশের অংশে একই সংখ্যা থাকে। এখানে একটি সংস্করণ যা পূর্ণসংখ্যা বা ভগ্নাংশ এবং যে কোনও ব্যাশ অপারেটরের জন্য কাজ করে:
#!/bin/bash
shopt -s extglob
fcomp() {
local oldIFS="$IFS" op=$2 x y digitx digity
IFS='.' x=( ${1##+([0]|[-]|[+])}) y=( ${3##+([0]|[-]|[+])}) IFS="$oldIFS"
while [[ "${x[1]}${y[1]}" =~ [^0] ]]; do
digitx=${x[1]:0:1} digity=${y[1]:0:1}
(( x[0] = x[0] * 10 + ${digitx:-0} , y[0] = y[0] * 10 + ${digity:-0} ))
x[1]=${x[1]:1} y[1]=${y[1]:1}
done
[[ ${1:0:1} == '-' ]] && (( x[0] *= -1 ))
[[ ${3:0:1} == '-' ]] && (( y[0] *= -1 ))
(( ${x:-0} $op ${y:-0} ))
}
for op in '==' '!=' '>' '<' '<=' '>='; do
fcomp $1 $op $2 && echo "$1 $op $2"
done
1.00000000000000000000000001
চেয়ে বড় 2
।
বাশ ভাসমান পয়েন্ট গণিত বুঝতে পারে না। এটি দশমিক বিন্দু যুক্ত সংখ্যাকে স্ট্রিং হিসাবে বিবেচনা করে।
পরিবর্তে awk বা বিসি ব্যবহার করুন।
#!/bin/bash
min=12.45
val=10.35
if [ 1 -eq "$(echo "${val} < ${min}" | bc)" ]
then
min=${val}
fi
echo "$min"
যদি আপনি প্রচুর গণিত ক্রিয়াকলাপ করার পরিকল্পনা করেন তবে অজগর বা পার্লের উপর নির্ভর করা ভাল।
আপনি সাধারণ ম্যানিপুলেশনের জন্য প্যাকেজ নাম্বার ব্যবহার করতে পারেন ...
আরও গুরুতর গণিতের জন্য, এই লিঙ্কটি দেখুন ... এটি বেশ কয়েকটি বিকল্পের বর্ণনা দেয়, যেমন।
একটি উদাহরণ numprocess
echo "123.456" | numprocess /+33.267,%2.33777/
# 67.0395291239087
A programs for dealing with numbers from the command line
The 'num-utils' are a set of programs for dealing with numbers from the
Unix command line. Much like the other Unix command line utilities like
grep, awk, sort, cut, etc. these utilities work on data from both
standard in and data from files.
Includes these programs:
* numaverage: A program for calculating the average of numbers.
* numbound: Finds the boundary numbers (min and max) of input.
* numinterval: Shows the numeric intervals between each number in a sequence.
* numnormalize: Normalizes a set of numbers between 0 and 1 by default.
* numgrep: Like normal grep, but for sets of numbers.
* numprocess: Do mathematical operations on numbers.
* numsum: Add up all the numbers.
* numrandom: Generate a random number from a given expression.
* numrange: Generate a set of numbers in a range expression.
* numround: Round each number according to its value.
এখানে একটি bash
হ্যাক ... এটি একটি স্ট্রিং বাম থেকে ডান তুলনা অর্থবহ করতে পূর্ণসংখ্যায় 0 টি যুক্ত করে। কোডের এই বিশেষ টুকরা প্রয়োজন যে উভয় মিনিট এবং Val আসলে একটি দশমিক বিন্দু এবং অন্তত একটি দশমিক অঙ্ক আছে।
min=12.45
val=10.35
MIN=0; VAL=1 # named array indexes, for clarity
IFS=.; tmp=($min $val); unset IFS
tmp=($(printf -- "%09d.%s\n" ${tmp[@]}))
[[ ${tmp[VAL]} < ${tmp[MIN]} ]] && min=$val
echo min=$min
আউটপুট:
min=10.35
ভাসমান পয়েন্ট সংখ্যাগুলিতে সাধারণ গণনার জন্য (+ - * / এবং তুলনা), আপনি awk ব্যবহার করতে পারেন।
min=$(echo 12.45 10.35 | awk '{if ($1 < $2) print $1; else print $2}')
অথবা, আপনার কাছে যদি ksh93 বা zsh (বাশ নয়) থাকে তবে আপনি নিজের শেলের বিল্ট-ইন গাণিতিক ব্যবহার করতে পারেন, যা ভাসমান পয়েন্ট সংখ্যা সমর্থন করে supports
if ((min>val)); then ((val=min)); fi
আরো উন্নত ফ্লোটিং পয়েন্ট গণনার জন্য, সন্ধান বিসি । এটি আসলে স্বেচ্ছাচারিতা-যথার্থ ফিক্সপয়েন্ট সংখ্যার উপর কাজ করে।
কমান্ডটিতে sort
একটি বিকল্প রয়েছে -g
( --general-numeric-sort
) যা তুলনায় <
"কম" বা " তুলনায় ব্যবহার করা যেতে পারে>
সর্বনিম্ন বা সর্বাধিক সন্ধান করে "এর চেয়ে "এর চেয়ে বড় ।
এই উদাহরণগুলি সর্বনিম্ন সন্ধান করছে:
$ printf '12.45\n10.35\n' | sort -g | head -1
10.35
এটি ই-নোটেশনের মতো ভাসমান পয়েন্ট সংখ্যাগুলির সাধারণ সাধারণ স্বরলিপি সহ কাজ করে
$ printf '12.45E-10\n10.35\n' | sort -g | head -1
12.45E-10
নোট করুন E-10
, প্রথম সংখ্যা তৈরি করে 0.000000001245
, সত্যিই কম 10.35
।
আইইইই 7575৫ , ভাসমান বিন্দুটির মানটি কয়েকটি বিশেষ মান নির্ধারণ করে। এই তুলনাগুলির জন্য, আকর্ষণীয় বিষয়গুলি INF
অসীমের জন্য। নেতিবাচক অনন্ত আছে; উভয়ই স্ট্যান্ডার্ডে ভাল সংজ্ঞাযুক্ত মান are
$ printf 'INF\n10.35\n' | sort -g | head -1
10.35
$ printf '-INF\n10.35\n' | sort -g | head -1
-INF
sort -gr
পরিবর্তে সর্বাধিক ব্যবহার সন্ধান করতে sort -g
, সাজানোর ক্রমটিকে বিপরীত করে:
$ printf '12.45\n10.35\n' | sort -gr | head -1
12.45
<
("এর চেয়ে কম") তুলনাটি বাস্তবায়নের জন্য , যাতে এটি if
ইত্যাদিতে ব্যবহার করা যায় , সর্বনিম্ন একটি মানের সাথে তুলনা করুন। যদি সর্বনিম্ন পাঠ্যের তুলনায় মানের সমান হয় তবে এটি অন্য মানের থেকে কম হয়:
$ a=12.45; b=10.35
$ [ "$a" = "$(printf "$a\n$b\n" | sort -g | head -1)" ]
$ echo $?
1
$ a=12.45; b=100.35
$ [ "$a" = "$(printf "$a\n$b\n" | sort -g | head -1)" ]
$ echo $?
0
a == min(a, b)
একই a <= b
। এটি লক্ষণীয় যে এটি এর চেয়ে কম কঠোরভাবে পরীক্ষা করে না। আপনি যদি এটি করতে চান তবে আপনার a == min(a, b) && a != max(a, b)
অন্য পাসওয়ার্ডগুলিতে পরীক্ষা করতে হবেa <= b and not a >= b
কেবল ব্যবহার করুন ksh
( ksh93
অবিকল) বা zsh
, যা উভয়ই স্থানীয়ভাবে ভাসমান পয়েন্ট গণিত সমর্থন করে:
$ cat test.ksh
#!/bin/ksh
min=12.45
val=10.35
if (( $val < $min )) ; then
min=$val
fi
echo "$min"
$ ./test.ksh
10.35
সম্পাদনা: দুঃখিত, আমি মিস করেছি ksh93
ইতিমধ্যে প্রস্তাবিত ছিল। খোলার প্রশ্নে পোস্ট করা স্ক্রিপ্টটি পরিষ্কার করার জন্য আমার উত্তরটি রাখা শেল স্যুইচের বাইরে কোনও পরিবর্তন ছাড়াই ব্যবহার করা যেতে পারে।
সম্পাদনা 2: নোট যাতে ksh93
পরিবর্তনশীল সামগ্রী আপনার লোকেলের সাথে সামঞ্জস্য করা প্রয়োজন, অর্থাত একটি ফরাসি লোকালের সাথে ডটের পরিবর্তে একটি কমা ব্যবহার করা উচিত:
...
min=12,45
val=10,35
...
আরও শক্তিশালী সমাধান হ'ল স্ক্রিপ্টের শুরুতে লোকাল সেট করা নিশ্চিত করা যে এটি ব্যবহারকারীর লোকাল নির্বিশেষে এটি কাজ করবে:
...
export LC_ALL=C
min=12.45
val=10.35
...
.
(তাই দশমিক বিভাজক যেখানে অর্ধ বিশ্বে নয় ,
)। zsh
যে সমস্যা নেই।
LC_ALL
, এর অর্থ হ'ল সংখ্যাটি ব্যবহারকারীর পছন্দের বিন্যাসে প্রদর্শিত হবে না (বা ইনপুট)। সম্ভাব্যতর উন্নত পদ্ধতির জন্য unix.stackexchange.com/questions/87745/ কি-does-lc-all-c-do/… দেখুন ।
.
যাই হোক না কেন।
min=$(echo "${min}sa ${val}d la <a p" | dc)
ব্যবহার করে dc
করতে ক্যালকুলেটর s
জন্য মান অর্ধবৃত্তাকার পার্শ্বচিত্রের মূর্তি $min
রেজিস্টারে a
এবং d
মান uplicates $val
তার প্রধান সঞ্চালনের স্ট্যাকের উপরে সম্মুখের। এরপরে এটি স্ট্যাকের শীর্ষে l
থাকা সামগ্রীগুলিকে নষ্ট করে a
দেয়, যে বিন্দুতে এটির মতো দেখাচ্ছে:
${min} ${val} ${val}
<
স্ট্যাকের বন্ধ দুটোতে এন্ট্রি পপ এবং তাদের তুলনা করা হয়। সুতরাং স্ট্যাকটি তখন দেখতে দেখতে:
${val}
উপরের এন্ট্রিটি যদি শীর্ষের থেকে দ্বিতীয়ের চেয়ে কম থাকে তবে বিষয়বস্তুগুলি a
উপরের দিকে ঠেলা দেয় , তাই স্ট্যাকটি দেখতে দেখতে:
${min} ${val}
অন্যথায় এটি কিছুই করে না এবং স্ট্যাকটি এখনও দেখতে দেখতে:
${val}
তারপরে এটি কেবল p
শীর্ষ স্ট্যাক এন্ট্রিটি মুদ্রণ করে।
সুতরাং আপনার সমস্যার জন্য:
min=12.45
val=12.35
echo "${min}sa ${val}d la <a p" | dc
###OUTPUT
12.35
কিন্তু:
min=12.45
val=12.55
echo "${min}sa ${val}d la <a p" | dc
###OUTPUT
12.45
কেন পুরানো, ভাল ব্যবহার করবেন না expr
?
বাক্য গঠন উদাহরণ:
if expr 1.09 '>' 1.1 1>/dev/null; then
echo 'not greater'
fi
জন্য সত্য এক্সপ্রেশন, expr প্রস্থান কোড 0, স্ট্রিং '1' stdout- এ পাঠানো হয়। মিথ্যা এক্সপ্রেশন জন্য বিপরীত ।
আমি এটি জিএনইউ এবং ফ্রিবিএসডি 8 এক্সপ্রেসের সাথে চেক করেছি।
expr 1.09 '<' -1.1
মুদ্রণ 1
এবং প্রস্থান করবে 0
।
দুটি (সম্ভবত ভগ্নাংশ) সংখ্যা ক্রমযুক্ত কিনা তা পরীক্ষা করার sort
জন্য (যুক্তিসঙ্গত) বহনযোগ্য:
min=12.45
val=12.55
if { echo $min ; echo $val ; } | sort -n -c 2>/dev/null
then
echo min is smallest
else
echo val is smallest
fi
তবে, আপনি যদি সর্বনিম্ন মানটি আপডেট রাখতে চান তবে আপনার প্রয়োজন হবে না if
। নম্বরগুলি বাছাই করুন এবং সর্বদা প্রথম (কমপক্ষে) একটি ব্যবহার করুন:
min=12.45
val=12.55
smallest=$({ echo $min ; echo $val ; } | sort -n | head -n 1)
echo $smallest
min=$smallest
সাধারণত আমি এমবেডেড পাইথন কোড সহ একই জিনিস করি:
#!/bin/sh
min=12.45
val=10.35
python - $min $val<<EOF
if ($min > $val):
print $min
else:
print $val
EOF
$ min=12.45
$ val=10.35
$ [ "$min" \< "$val" ] && echo $val || echo $min
$ 12.45
$ val=13
$ [ "$min" \< "$val" ] && echo $val || echo $min
$ 13
0.5
এবং0.06
)। দশমিক স্বরলিপিটি ইতিমধ্যে বোঝে এমন একটি সরঞ্জাম আপনি আরও ভাল ব্যবহার করতে চাইবেন।