ZSH में, सरणी उप-धारा के रूप में क्या अंकगणितीय अभिव्यक्ति दिखाई दे सकती हैं?
ZSH मैनुअल ( zshparam(1)
) पढ़ता है:
Array Subscripts
Individual elements of an array may be selected using a subscript. A
subscript of the form `[exp]' selects the single element exp, where
exp is an arithmetic expression which will be subject to arithmetic
expansion as if it were surrounded by `$((...))'.
हालाँकि, यह जल्दी विफल हो जाता है:
mc% arr=(a b c d e)
mc% echo $arr[$#arr] e mc% echo $arr[$(($#arr))]
e
mc% echo $arr[$(($#arr - 1))] d mc% echo $arr[$#arr - 1]
zsh: invalid subscript
प्रश्न: क्यों, और अपवाद क्या हैं?
नोट: यह प्रश्न don_crissti के उत्तर से उपजा है , जहां वे $arr[RANDOM % $#arr + 1]
एक यादृच्छिक तत्व तक पहुंचने का सुझाव देते हैं , लेकिन यह उपरोक्त त्रुटि को बढ़ाता है ।
जवाब
तकनीकी रूप से, कोई भी अभिव्यक्ति एक सबस्क्रिप्ट के रूप में दिखाई दे सकती है। समस्या यह है कि पार्सर को सबस्क्रिप्ट में आप क्या चाहते हैं। रिक्त स्थान सहित कुछ वर्ण, इसे कभी नहीं बनाते हैं। केवल शब्द घटक वर्ण ही सबस्क्रिप्ट का हिस्सा हो सकते हैं, क्योंकि सबस्क्रिप्ट एक शब्द का हिस्सा है।
mc% echo $arr[ 1] zsh: invalid subscript mc% echo $arr[1 ]
zsh: invalid subscript
mc% echo $arr[$#arr - 1]
zsh: invalid subscript
mc% echo $arr[$#arr-1]
d
सबस्क्रिप्ट पार्सर पहले अमान्य वर्ण पर रुकता है, और "अमान्य सबस्क्रिप्ट" त्रुटि को ट्रिगर करने से पहले ही zsh भी बंद ब्रैकेट की जाँच करता है।
mc% echo $arr[ 1
zsh: invalid subscript
में echo $arr[ 1]
, अंतरिक्ष के बाद वाले हिस्से वास्तव में एक अलग शब्द माना जाता है: echo
के विस्तार से उत्पन्न दो तर्क प्राप्त होगा $arr[
और 1]
, सिवाय इसके कि zsh पार्स विफलता की वजह से किसी भी आदेश को क्रियान्वित करने शुरू नहीं करता है। कुछ मामले हैं जहां आप बता सकते हैं कि अंकगणित की अभिव्यक्ति के हिस्से के रूप में आप क्या सोच सकते हैं, उदाहरण के लिए, इस तरह से पार्स नहीं किया गया है:
mc% echo $arr[1<<2]
heredoc> << is a heredoc operator, not part of the subscript.
heredoc> 2]
zsh: invalid subscript
गैर-शब्द-घटक वर्ण निश्चित रूप से एक नेस्टेड विस्तार जैसे कि एक अंकगणितीय अभिव्यक्ति या कमांड प्रतिस्थापन के रूप में चुपके कर सकते हैं।
mc% echo $arr[$[1&3]]
a
mc% echo $arr[`echo "1 + 2"`]
c
यदि पैरामीटर विस्तार डबल कोट्स में है, तो कोई भी चरित्र (एक संतुलित क्लोजिंग ब्रैकेट या एक अंतिम उद्धरण के अलावा) सबस्क्रिप्ट का हिस्सा होता है। ऐसा इसलिए है क्योंकि दोहरे उद्धरण चिह्नों के अंदर, कोई भी चरित्र प्रभावी रूप से एक शब्द घटक है। इसी तरह, यदि पैरामीटर विस्तार ब्रेसेस का उपयोग करता है, तो zsh पैरामीटर विस्तार के लिए क्लोजिंग ब्रेस की तलाश करता है, क्योंकि }
यह ]
सबस्क्रिप्ट के लिए कोष्ठक के लिए दिखता है , और इसलिए गैर-शब्द-घटक वर्ण इसे सबस्क्रिप्ट में बनाते हैं।
mc% echo "$arr[$#arr - 1]" d mc% echo ${arr[$#arr - 1]}
d
यदि आप नॉटी-ग्रिट्टी डिटेल्स में गोता लगाना चाहते हैं, तो संबंधित फ़ंक्शन को parse_subscriptकहा जाता है getindex।