কোনও ভেরিয়েবলকে স্ট্রিং বা ইন্ট হিসাবে হিসাবে তুলনা করার সময় কি কোনও বড় পার্থক্য রয়েছে?


22

কৌতূহলের বাইরে, যখন কোনও ব্যাশ ভেরিয়েবল তুলনা করা হয় (এর মান এটি হ'ল integer) এটি কোনও পূর্বনির্ধারিত মানের সাথে হয় হিসাবে ঘোষণা করা হয় intবা হিসাবে হিসাবে এটি পরীক্ষা করা সম্ভব string

নমুনা লিপি :

#!/bin/bash
f1()
{
        [ "$1" == "1" ] && echo "$FUNCNAME: \"1\" compared as string"
}

f2()
{
        [[ "$1" -eq 1 ]] && echo "$FUNCNAME: \"1\" compared as int"
}

f1 $1
f2 $1

আউটপুট :

$  ./param.sh 1
f1: "1" compared as string
f2: "1" compared as int

এবং

$  ./param.sh blah
$

উভয় ফাংশন একইভাবে আচরণ করে এবং তাই আমি ভাবছি যে কোনও পূর্ণসংখ্যার ভেরিয়েবলটি পরীক্ষা করার সময় কোনও পছন্দসই উপায় আছে কিনা? এটি আরও কঠোর হওয়ায় আমি intবনাম যাচাই করতে যাব intতবে আমি ভাবছি যে এটির সাথে কোনও ড্র ব্যাক রয়েছে কিনা string?

এই ক্ষেত্রে, f2()তুলনা সম্পর্কে আরও কঠোর, অর্থাত্ দশমিক মান পাস করা এটি ভেঙে দেবে, যেখানে f1()কোনও সমস্যা হবে না।


দ্রষ্টব্য যে বাশের কাছে সত্যই কোনও পূর্ণসংখ্যার ডেটাটাইপ নেই। আপনি স্ট্রিংকে একটি পূর্ণসংখ্যা হিসাবে বিবেচনা করতে মূলত বাশকে ইঙ্গিত করতে পারেন।
হেল্পারমেডো

উত্তর:


18

হ্যাঁ, প্রচুর পার্থক্য। উদাহরণস্বরূপ, =সঠিক স্ট্রিং সমতা জন্য পরীক্ষা করে, তবে -eqসমতা পরীক্ষা করার আগে উভয় এক্সপ্রেশনকে গাণিতিকভাবে মূল্যায়ন করে:

$ [ " 1 " -eq 1 ] && echo equal || echo not
equal
$ [ " 1 " = 1 ] && echo equal || echo not
not

$ [ +1 -eq 1 ] && echo equal || echo not
equal
$ [ +1 = 1 ] && echo equal || echo not
not

$ [ "0+1" -eq 1 ] && echo equal || echo not
equal
$ [ "0+1" = 1 ] && echo equal || echo not
not

এছাড়াও, খালি স্ট্রিংটি সংখ্যাগতভাবে শূন্যের সমান হয়:

$ [ "" -eq 0 ] && echo equal || echo not
equal
$ [ "" = 0 ] && echo equal || echo not
not

এবং তুলনামূলক অপারেটরদের আনার সময় পুরো অন্যান্য শ্রেণির পার্থক্য দেখা দেয় - <বনাম বিবেচনা করে -lt:

$ [[ 2 -lt 10 ]] && echo less || echo not
less
$ [[ 2 < 10 ]] && echo less || echo not
not

এটি কারণ "2" স্ট্রিং বর্ণমালিকভাবে "10" স্ট্রিংয়ের পরে (যেহেতু 1 2 এর আগে আসে), তবে "2" সংখ্যাটি "10" সংখ্যার তুলনায় সংখ্যাগতভাবে কম হয়।


2
(( ... ))সংখ্যার ক্রিয়াকলাপের জন্যও ভুলে যাবেন না । (( " 1 " == 1 )) && echo yes || echo noফলাফলyes
প্যাট্রিক

7

আপনি যখন আরও বেশি বা তার চেয়ে কম তুলনা করছেন তখন পূর্ণসংখ্যা বনাম স্ট্রিং তুলনা সর্বাধিক তাৎপর্যপূর্ণ হয়ে ওঠে:

#!/bin/bash

eleven=11
nine=9

[[ $nine < $eleven ]] && echo string   # fail

[[ "$nine" -lt "$eleven" ]] && echo integer # pass

প্রথমটি ব্যর্থ হয় কারণ 9 এর পরে 11 আসে যখন ডিক্সিকোগ্রাফিকভাবে বাছাই করা হয়।

নোট করুন যে কোটগুলি ব্যবহার করে তা নির্ধারণ করে না আপনি স্ট্রিং বা সংখ্যার তুলনা করছেন কিনা, অপারেটর তা করে। আপনি উপরের উদ্ধৃতিগুলি যোগ করতে বা সরাতে পারেন, এতে কোনও তফাত আসে না। বাশ ডাবল বন্ধনীগুলির মধ্যে অপরিবর্তিত ভেরিয়েবলগুলি ক্যাচ করে, সুতরাং উদ্ধৃতিগুলি আবশ্যক নয়। সংখ্যাগত পরীক্ষাগুলির জন্য একক বন্ধনী সহ উদ্ধৃতি ব্যবহার করা আপনাকে আর সংরক্ষণ করবে না:

[ "" -lt 11 ]

যাইহোক একটি ত্রুটি ("পূর্ণসংখ্যার এক্সপ্রেশন প্রয়োজন")। উদ্ধৃতিগুলি একটি একক বন্ধনীতে স্ট্রিং তুলনা সহ একটি কার্যকর সুরক্ষার ব্যবস্থা:

[ "" \< 11 ]

মধ্যে উল্লেখ্য ডবল বন্ধনী, ""হবে -eq 0কিন্তু == 0


1
ব্যাশে, ডাবল বন্ধনীগুলির মধ্যে ভেরিয়েবলগুলি উদ্ধৃত করার জন্য কঠোরভাবে প্রয়োজন হয় না: বিল্টিনগুলি [[ভেরিয়েবলগুলি কোথায় তা মনে রাখার জন্য যথেষ্ট স্মার্ট এবং এটি খালি ভেরিয়েবল দ্বারা বোকা হয়ে উঠবে না। একক বন্ধনী ( [) এর এই বৈশিষ্ট্যটি নেই এবং এর উদ্ধৃতি প্রয়োজন।
গ্লেন জ্যাকম্যান

@glennjackman এটি লক্ষ্য করেনি। [[ -lt 11 ]]একটি ত্রুটি, কিন্তু nothing=; [[ $nothing -lt 11 ]]না। আমি শেষ অনুচ্ছেদে কিছুটা পুনরায় কাজ করেছি।
গোল্ডিলোকস

2

এ ছাড়া যা বলা হয়েছে।
সমতার জন্য তুলনা সংখ্যাগুলির সাথে দ্রুততর, যদিও শেল স্ক্রিপ্টিংয়ে এটি খুব কমই আপনার খুব দ্রুত গণনার প্রয়োজন।

$ b=234
$ time for ((a=1;a<1000000;a++)); do [[ $b = "234" ]]; done

real    0m13.008s
user    0m12.677s
sys 0m0.312s

$ time for ((a=1;a<1000000;a++)); do [[ $b -eq 234 ]]; done

real    0m10.266s
user    0m9.657s
sys 0m0.572s

তারা বিভিন্ন কাজ করে তা বিবেচনা করে, আমি বলব পারফরম্যান্সটি অপ্রাসঙ্গিক - আপনাকে যা করতে চান তা ব্যবহার করতে হবে।
গডলিজিক

@godlygeek একটি চলকের সমতার তুলনা উভয় উপায়ে অর্জন করা যায়। "-eq" দ্রুত।
এমমানুয়েল

তারা সাম্যের বিভিন্ন সংজ্ঞা পরীক্ষা করে test যদি আপনি "এই পরিবর্তনশীলটি সঠিক স্ট্রিং 123 টি ধারণ করে" এই প্রশ্নের উত্তর দিতে চান তবে আপনি কেবলমাত্র ব্যবহার করতে পারবেন =, যেহেতু -eqব্যবহারটি "+123" এর সাথেও মেলে। যদি আপনি জানতে চান "এটি কি এই পরিবর্তনশীল, যখন গাণিতিক এক্সপ্রেশন হিসাবে মূল্যায়ন করা হয় তখন 123 এর সমান তুলনা করুন", আপনি কেবল ব্যবহার করতে পারেন -eq। আমি যখন দেখতে পেলাম যে কোনও প্রোগ্রামার যখন সাম্যতার কোন সংজ্ঞা ব্যবহৃত হয়েছিল তখন সেদিকে খেয়াল রাখে না, যখন তিনি জানেন যে ভেরিয়েবলের বিষয়বস্তু সময়ের আগে নির্দিষ্ট বিন্যাসে আবদ্ধ থাকে।
গডলিজিক

@ গুডলিগেক আকর্ষণীয়, প্রশ্নটি সংখ্যার সমতার তুলনা করার বিষয়ে ছিল যেন তারা স্ট্রিং ছিল, এটি কি নির্দিষ্ট সময়ের সাথে সামঞ্জস্য করা ভেরিয়েবলগুলির ক্ষেত্রে ফিট করে?
এমমানুয়েল

আপনার উদাহরণ ( b=234) সেই প্যাটার্নটির সাথে খাপ খায় - আপনি জানেন যে এটি +234 বা "234" বা "233 + 1" নয়, যেহেতু আপনি এটিকে নিজেরাই নির্ধারণ করেছেন, সুতরাং আপনি জানেন যে এটি একটি স্ট্রিং এবং একটি সংখ্যার হিসাবে তুলনা করা সমানভাবে বৈধ। তবে ওপি-র স্ক্রিপ্ট, যেহেতু এটি কমান্ড লাইন আর্গুমেন্ট হিসাবে ইনপুট নেয়, তাতে বাধা নেই - এটিকে হিসাবে ./param.sh 0+1বা ডাকে বিবেচনা করুন./param.sh " 1"
গডলিজিক
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.