तुलना पूर्णांक: अंकगणितीय अभिव्यक्ति या सशर्त अभिव्यक्ति


20

बैश में, दो पूर्णांक सशर्त अभिव्यक्ति का उपयोग करके तुलना की जा सकती है

arg1 ओपी arg2

ओपी में से एक है -eq, -ne, -lt, -le, -gt, या -ge। ये अंकगणित बाइनरी ऑपरेटर्स सही साबित होते हैं, अगर arg1 , क्रमशः, arg2 के बराबर, से कम, कम या अधिक, बराबर या उससे अधिक, बराबर या arg2 के बराबर के बराबर नहीं है । Arg1 और arg2 सकारात्मक या नकारात्मक पूर्णांक हो सकते हैं।

या अंकगणितीय अभिव्यक्ति:

<= >= < > तुलना

== != समानता और असमानता

दो पूर्णांकों की तुलना करने के लिए हमारे पास दो अलग-अलग तरीके क्यों हैं? कब कौन सा उपयोग करें?

उदाहरण के लिए, [[ 3 -lt 2 ]]सशर्त अभिव्यक्ति का (( 3 < 2 ))उपयोग करता है , और अंकगणितीय अभिव्यक्ति का उपयोग करता है। तुलनात्मक सत्य होने पर दोनों वापस लौट आते हैं

जब दो पूर्णांकों की तुलना की जाती है, तो क्या इन दोनों विधियों का हमेशा परस्पर विनिमय किया जा सकता है? यदि हाँ, तो बैश में एक के बजाय दो तरीके क्यों हैं?


1
= != < <= > >=तार की तुलना करें । 1 -eq 01लेकिन 1 != 01और 8 -lt 42लेकिन8 > 42
dave_thompson_085

वे अंकगणितीय अभिव्यक्तियों में अतिभारित हैं।
टिम

1
आपको बैश चैंज में खोज करना होगा कि प्रत्येक सुविधा को कब जोड़ा गया था। मुझे संदेह है कि परीक्षण कमांड की तुलना में अंकगणितीय अभिव्यक्तियों को बहुत बाद में जोड़ा गया था।
ग्लेन जैकमैन

मैं तार की तुलना करने के बारे में नहीं पूछ रहा हूं। @muru।
टिम

जवाबों:


28

हां, हमारे पास दो पूर्णांकों की तुलना करने के दो अलग-अलग तरीके हैं।

ऐसा लगता है कि इन तथ्यों को इस मंच में व्यापक रूप से स्वीकार नहीं किया गया है:

  1. मुहावरा अंदर [ ]गणित की तुलना के लिए ऑपरेटर हैं -eq, -ne, -lt, -le, -gtऔर -ge

    के रूप में वे भी एक टेस्ट कमांड के अंदर और एक अंदर हैं [[ ]]

    हाँ इस मुहावरे के अंदर, =, <, आदि स्ट्रिंग ऑपरेटरों रहे हैं।

  2. मुहावरा अंदर (( ))गणित की तुलना के लिए ऑपरेटर हैं ==, !=, <, <=, >, और >=

    नहीं, यह एक "अंकगणित विस्तार" नहीं है (जो कि एक से शुरू होता है $) $(( ))। इसे मैन बैश में "कम्पाउंड कमांड" के रूप में परिभाषित किया गया है।

    हां, यह "अंकगणित विस्तार" के समान नियमों (आंतरिक रूप से) का अनुसरण करता है, लेकिन इसका कोई आउटपुट नहीं है, केवल एक निकास मूल्य है। यह इस तरह इस्तेमाल किया जा सकता है:

if (( 2 > 1 )); then ...

दो पूर्णांकों की तुलना करने के लिए हमारे पास दो अलग-अलग तरीके क्यों हैं?

मुझे लगता है कि उत्तरार्द्ध (( ))को अंकगणितीय परीक्षणों को करने के लिए एक सरल तरीके के रूप में विकसित किया गया था। यह लगभग वैसा ही है $(( ))लेकिन अभी इसका कोई आउटपुट नहीं है।

दो क्यों? वैसे ही क्यों हम दो printf(बाहरी और अंतर्निहित) या चार परीक्षण (बाहरी test, अंतर्निहित test, [और [[) है। यही कारण है कि गोले बढ़ते हैं, एक वर्ष में कुछ क्षेत्र में सुधार करते हैं, अगले वर्ष कुछ और सुधार करते हैं।

कब कौन सा उपयोग करें?

यह एक बहुत ही कठिन प्रश्न है क्योंकि कोई प्रभावी अंतर नहीं होना चाहिए। बेशक एक [ ]काम और (( ))आंतरिक रूप से काम करने के तरीके में कुछ अंतर हैं , लेकिन: दो पूर्णांकों की तुलना करना बेहतर है? किसी को!।

जब दो पूर्णांकों की तुलना की जाती है, तो क्या इन दोनों विधियों का हमेशा परस्पर विनिमय किया जा सकता है?

दो नंबर के लिए मैं हां कहने के लिए मजबूर हूं।
लेकिन चर, विस्तार, गणितीय कार्यों के लिए महत्वपूर्ण अंतर हो सकते हैं जो एक या दूसरे का पक्ष लेना चाहिए। मैं यह नहीं कह सकता कि दोनों बिल्कुल समान हैं। एक के लिए, (( ))क्रम में कई गणित संचालन कर सकते हैं:

if (( a=1, b=2, c=a+b*b )); then echo "$c"; fi

यदि हाँ, तो बैश में एक के बजाय दो तरीके क्यों हैं?

यदि दोनों सहायक हैं, तो क्यों नहीं?


1
=एक असाइनमेंट है और ==अंकगणितीय विस्तार में तुलना है। प्रश्न इसे सही ढंग से उद्धृत करता है। लेकिन जवाब गलत है।
16:16

12

ऐतिहासिक रूप से, testकमान पहले अस्तित्व में थी ( 1979 में कम से कम यूनिक्स सातवें संस्करण में वापस आ गई )। यह ऑपरेटरों का उपयोग किया =और !=तार तुलना करने के लिए, और -eq, -ne, -lt, आदि संख्याओं की तुलना करने के लिए। उदाहरण के लिए, test 0 = 00गलत है, लेकिन test 0 -eq 00सच है। मुझे नहीं पता कि इस सिंटैक्स को क्यों चुना गया था, लेकिन इसका उपयोग करने से बचने के लिए हो सकता है <और >, जो शेल को पुनर्निर्देशित ऑपरेटरों के रूप में पार्स किया गया होगा। testआदेश कुछ साल बाद एक और वाक्य रचना है: [ … ]के बराबर है test …

[[ … ]]सशर्त वाक्य रचना है, जो अंदर <और >के हवाले से बिना ऑपरेटर के रूप में इस्तेमाल किया जा सकता है, बाद में ksh में जोड़ा गया है,। इसने पिछड़ी संगतता को बनाए रखा [ … ], इसलिए इसने समान ऑपरेटरों का उपयोग किया, लेकिन जोड़ा <और >तार की तुलना करना (उदाहरण के लिए, [[ 9 > 10 ]]लेकिन [[ 9 -lt 10 ]])। अधिक जानकारी के लिए, एकल या डबल ब्रैकेट का उपयोग करके देखें - बैश

अंकगणित भाव भी बाद में की तुलना में आया testआदेश, कॉर्न खोल में , 1980 के दशक में कुछ समय में। उन्होंने सी भाषा के वाक्य विन्यास का अनुसरण किया, जो यूनिक्स हलकों में बहुत लोकप्रिय था। इस प्रकार उन्होंने सी के ऑपरेटरों का उपयोग किया: ==समानता के लिए, <=कम-या-बराबर आदि के लिए।

यूनिक्स सातवें संस्करण में अंकगणितीय अभिव्यक्तियां नहीं थीं, लेकिन इसमें exprकमांड थी , जिसने पूर्णांक संचालन के लिए सी-जैसे सिंटैक्स लागू किया, जिसमें इसके तुलनात्मक ऑपरेटर भी शामिल थे। एक खोल स्क्रिप्ट में, इसके पात्र <और >था उन्हें खोल से बचाने के लिए उद्धृत किया जा करने के लिए, उदाहरण के लिए if expr 1 \< 2; …के बराबर है if test 1 -lt 2; …। शेल में अंकगणितीय अभिव्यक्तियों के अलावा exprअप्रचलित के अधिकांश उपयोग किए गए हैं , इसलिए यह आज अच्छी तरह से ज्ञात नहीं है।

एक स्क्रिप्ट में, आप एक पूर्णांक मान की गणना करने के लिए, और [ … ]पूर्णांकों की तुलना करने के लिए आम तौर पर अंकगणितीय अभिव्यक्तियों का उपयोग करेंगे ।

if [ "$((x + y))" -lt "$z" ]; then 

एक ksh, bash या zsh स्क्रिप्ट में, आप ((…))दोनों के लिए उपयोग कर सकते हैं ।

if ((x + y < z)); then 

[[ … ]]आप पूर्णांक के अलावा अन्य चीजों को शामिल सशर्त उपयोग करना चाहते हैं रूप से उपयोगी है।


1

परीक्षण मैन पेज के अनुसार, = और! = स्ट्रिंग तुलना के लिए उपयोग किया जाता है जबकि भाव -eq, -gt, -lt, -le, और -ne पूर्णांक तुलना हैं। शेल स्क्रिप्ट लिखते समय मैंने हमेशा इस सम्मेलन का पालन किया है और यह हमेशा काम करता है। ध्यान रखें कि यदि आपके पास अभिव्यक्ति में चर हैं, तो आपको शून्य तुलना करने से बचने के लिए चर को किसी तरह से उद्धृत करना पड़ सकता है।

कागज पर, हम बिना ज्यादा सोचे-समझे स्ट्रिंग / नंबर की तुलना करते हैं। दूसरी तरफ एक कंप्यूटर नहीं जानता कि क्या 987 एक संख्या या वर्णों का एक स्ट्रिंग है। आपको कंप्यूटर को बताने के लिए विभिन्न ऑपरेटरों की आवश्यकता है ताकि आपको सही परिणाम मिल सके। यहाँ कुछ अतिरिक्त जानकारी है जो कुछ इतिहास की व्याख्या करती है। अनिवार्य रूप से, चर अयोग्य हैं और ऐतिहासिक संगतता के लिए इस तरह बने हुए हैं।


मेरे पोस्ट में, = और !=अंकगणित ऑपरेटर हैं, जबकि testकेवल सशर्त अभिव्यक्ति ऑपरेटरों का मैनपेज दिखाता है।
टिम
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.