expr
कोष्ठक की तरह नहीं लगता है (स्पष्ट ऑपरेटर प्राथमिकता के लिए गणित में प्रयुक्त):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
बाश में ऑपरेटर प्राथमिकता को कैसे व्यक्त करें?
expr
कोष्ठक की तरह नहीं लगता है (स्पष्ट ऑपरेटर प्राथमिकता के लिए गणित में प्रयुक्त):
expr 3 * (2 + 1)
bash: syntax error near unexpected token `('
बाश में ऑपरेटर प्राथमिकता को कैसे व्यक्त करें?
जवाबों:
let
बैश बिलिन का उपयोग करने का दूसरा तरीका :
$ let a="3 * (2 + 1)"
$ printf '%s\n' "$a"
9
ध्यान दें
जैसा कि @ स्टीफन चेज़ेलस ने कहा , bash
आपको विरासत में या उससे ((...))
अधिक अंकगणित करने के लिए उपयोग करना चाहिए ।expr
let
पोर्टेबिलिटी के लिए $((...))
, @ बर्नहार्ड जवाब की तरह उपयोग करें ।
let
। यह किसी भी अधिक मानक या पोर्टेबल की तुलना में नहीं है (( a = 3 * (2 + 1) ))
(दोनों से आते हैं ksh
और केवल ksh, bash और zsh में उपलब्ध हैं) और यह कम सुपाठ्य या उद्धरण के लिए आसान है। a=$((3 * (2 + 1)))
पोर्टेबल होने के लिए उपयोग करें ।
((a = 3 * (2 + 1) ))
लिए एक है, पोर्टेबिलिटी के लिए एक a=$((3 * (2 + 1)))
), इसलिए यह आपके या आपके उत्तर के खिलाफ नोट नहीं है लेकिन इसके लिए चयनित उत्तर होने के खिलाफ है और शीर्ष स्कोरर।
a=1 $[a+2]
या a=1 b=2 $[a+b]
। क्या उनका कारण उस वाक्य रचना से बचना है?
आप इसके बजाय अंकगणितीय विस्तार का उपयोग कर सकते हैं।
echo "$(( 3 * ( 2 + 1 ) ))"
9
मेरी व्यक्तिगत राय में, यह प्रयोग करने की तुलना में थोड़ा अच्छा है expr
।
से man bash
अंकगणित विस्तार अंकगणित विस्तार एक अंकगणितीय अभिव्यक्ति के मूल्यांकन और परिणाम के प्रतिस्थापन की अनुमति देता है। अंकगणितीय विस्तार के लिए प्रारूप है:
$((expression))
अभिव्यक्ति को ऐसे माना जाता है जैसे कि यह दोहरे उद्धरण चिह्नों के भीतर है, लेकिन कोष्ठकों के अंदर एक दोहरे उद्धरण का विशेष रूप से व्यवहार नहीं किया जाता है। अभिव्यक्ति में सभी टोकन पैरामीटर विस्तार, स्ट्रिंग विस्तार, कमांड प्रतिस्थापन और उद्धरण हटाने से गुजरते हैं। अंकगणित विस्तार को नेस्टेड किया जा सकता है।
मूल्यांकन ARITHMETIC EVALUATION के तहत नीचे सूचीबद्ध नियमों के अनुसार किया जाता है। यदि अभिव्यक्ति अमान्य है, तो बैश एक संदेश को दर्शाता है जो विफलता का संकेत देता है और कोई प्रतिस्थापन नहीं होता है।
expr
आधुनिक गोले में अंकगणित का उपयोग करने का कोई कारण नहीं है ।
POSIX $((...))
विस्तार ऑपरेटर को परिभाषित करता है । तो आप सभी POSIX आज्ञाकारी गोले में ( sh
सभी आधुनिक यूनिक्स-पसंद, डैश, बैश, यश, mshh, zsh, पॉश, ksh ...) का उपयोग कर सकते हैं।
a=$(( 3 * (2 + 1) ))
a=$((3*(2+1)))
ksh
एक let
बिल्टिन भी पेश किया, जो एक ही तरह की अंकगणितीय अभिव्यक्ति के रूप में दिया गया है, कुछ में विस्तार नहीं करता है, लेकिन अभिव्यक्ति के 0 या नहीं के आधार पर बाहर निकलने की स्थिति देता है, जैसे expr
:
if let 'a = 3 * (2 + 1)'; then
echo "$a is non-zero"
fi
हालाँकि, जैसा कि उद्धरण इसे अजीब बनाता है और बहुत सुपाठ्य नहीं है ( expr
निश्चित रूप से उसी हद तक नहीं ), ksh
एक ((...))
वैकल्पिक विकल्प भी प्रस्तुत किया है :
if (( a = 3 * (2 + 1) )) && (( 3 > 1 )); then
echo "$a is non-zero and 3 > 1"
fi
((a+=2))
जो बहुत अधिक सुपाठ्य है और इसके स्थान पर इसका उपयोग किया जाना चाहिए।
let
और ((...))
में ही उपलब्ध हैं ksh
, zsh
और bash
। $((...))
वाक्य रचना प्राथमिकता दी जानी चाहिए अगर अन्य गोले को पोर्टेबिलिटी की जरूरत है, expr
केवल पूर्व POSIX बॉर्न की तरह गोले (आमतौर पर बॉर्न शैल या Almquist खोल के प्रारंभिक संस्करणों) के लिए आवश्यक है।
गैर-बॉर्न मोर्चे पर, अंतर्निहित अंकगणित ऑपरेटर के साथ कुछ गोले हैं:
csh
/ tcsh
(वास्तव में अंकगणित मूल्यांकन के साथ पहला यूनिक्स खोल)
@ a = 3 * (2 + 1)
akanga
(पर आधारित rc
)
a = $:'3 * (2 + 1)'
एक इतिहास के रूप में, अल्मक्विस्ट शेल के मूल संस्करण, जैसा कि 1989 में यूनेट पर पोस्ट किया गया था, में एक expr
बिल्डिन (वास्तव में विलय हुआ test
) था, लेकिन इसे बाद में हटा दिया गया था।
: $((a = a*2))
?
$((...))
जो zsh, ksh93 या यश जैसे फ्लोटिंग पॉइंट का समर्थन करता है ।
expr
एक बाहरी कमांड है, यह विशेष शेल सिंटैक्स नहीं है। इसलिए, यदि आप expr
शेल विशेष वर्णों को देखना चाहते हैं, तो आपको उन्हें उद्धृत करके शेल पार्सिंग से बचाने की आवश्यकता है। इसके अलावा, expr
प्रत्येक संख्या और ऑपरेटर को एक अलग पैरामीटर के रूप में पारित करने की आवश्यकता होती है। इस प्रकार:
expr 3 \* \( 2 + 1 \)
जब तक आप 1970 या 1980 के दशक से एक प्राचीन यूनिक्स प्रणाली पर काम नहीं कर रहे हैं, तब तक उपयोग करने का बहुत कम कारण है expr
। पुराने दिनों में, गोले में अंकगणित करने के लिए एक अंतर्निहित तरीका नहीं था, और आपको expr
इसके बजाय उपयोगिता को कॉल करना था । सभी POSIX गोले में अंकगणित विस्तार सिंटैक्स के माध्यम से अंकगणित है ।
echo "$((3 * (2 + 1)))"
निर्माण $((…))
अंकगणित अभिव्यक्ति (दशमलव में लिखा गया) के परिणाम तक फैलता है। बैश, अधिकांश गोले की तरह, केवल पूर्णांक अंकगणितीय मोडुलो 2 64 (या 32 बिट मशीनों पर बैश के पुराने संस्करणों और कुछ अन्य गोले के लिए मॉडुलो 2 32 ) का समर्थन करता है।
बैश एक अतिरिक्त सुविधा सिंटैक्स प्रदान करता है जब आप असाइनमेंट निष्पादित करना चाहते हैं या परीक्षण करना चाहते हैं कि कोई अभिव्यक्ति 0 है, लेकिन परिणाम के बारे में परवाह नहीं है। यह निर्माण ksh और zsh में भी मौजूद है लेकिन सादे श में नहीं।
((x = 3 * (2+1)))
echo "$x"
if ((x > 3)); then …
पूर्णांक अंकगणितीय के अलावा, expr
कुछ स्ट्रिंग हेरफेर फ़ंक्शन प्रदान करता है। ये भी POSIX गोले की विशेषताओं के आधार पर तय किए गए हैं, एक को छोड़कर: यह expr STRING : REGEXP
परीक्षण करता है कि क्या स्ट्रिंग निर्दिष्ट regexp से मेल खाती है। एक POSIX शेल बाहरी उपकरणों के बिना ऐसा नहीं कर सकता है, लेकिन bash [[ STRING =~ REGEXP ]]
(एक अलग regexp सिंटैक्स के साथ - expr
एक क्लासिक टूल है और BRE का उपयोग करता है, bash ERE का उपयोग करता है)।
जब तक आप 20-वर्षीय सिस्टम पर चलने वाली स्क्रिप्ट्स को मेनटेन नहीं कर रहे हैं, आपको यह जानने की आवश्यकता नहीं है कि expr
कभी अस्तित्व में था। शेल अंकगणित का उपयोग करें।
expr foo : '\(.\)'
पाठ निष्कर्षण भी करता है। bash
की BASH_REMATCH
ऐसी ही कुछ प्राप्त होता है। यह स्ट्रिंग तुलना भी करता है, जो कि POSIX [
नहीं करता है (हालांकि कोई इसके लिए उपयोग करने के तरीकों की कल्पना कर सकता sort
है)।
उद्धरण के साथ कोष्ठक का प्रयोग करें:
expr 3 '*' '(' 2 '+' 1 ')'
9
उद्धरण को कोष्ठक के रूप में कोष्ठक की व्याख्या करने से बैश को रोकते हैं।
expr
कमांड लाइन पर टोकन को रिक्त स्थान द्वारा अलग किया जाना चाहिए; इसलिए; उदाहरण के लिए, expr 3 "*" "(2" "+" "1)"
काम नहीं करेगा । (इसके अलावा, BTW, आपको शायद उद्धृत करने की आवश्यकता नहीं है +
।)
while
और [[
, वे वाक्यविन्यास हैं। यदि वे कीवर्ड थे, तो उन्हें इस तरह के कमांड तर्क में व्याख्यायित नहीं किया जाएगा। आपको उद्धरण चिह्नों की आवश्यकता होती है ताकि बैश उन्हें पार्स न करे, बल्कि एक स्ट्रिंग शाब्दिक देखता है