मान लें कि आप बॉर्न की तरह गोले (कई अन्य गोले पसंद करने के लिए प्रतिबंधित करना चाहते हैं csh
, tcsh
, rc
, es
या fish
समर्थन सरणियों लेकिन एक स्क्रिप्ट के गोले की तरह बॉर्न को एक ही समय में संगत लेखन और उन मुश्किल और आम तौर पर व्यर्थ है के रूप में वे पूरी तरह से अलग और के लिए दुभाषिए हैं असंगत भाषाएं), ध्यान दें कि कार्यान्वयन के बीच महत्वपूर्ण अंतर हैं।
बॉर्न जैसे गोले जो कि ऐरे का समर्थन करते हैं:
ksh88
(यह पहले लागू करने वाला सरणियाँ है, ksh88 अभी भी ksh
सबसे पारंपरिक वाणिज्यिक यूनियनों के रूप में पाया जाता है जहां यह इसके लिए आधार भी है sh
)
- सरणियाँ एक आयामी हैं
- Arrays को परिभाषित किया जाता है
set -A array foo bar
या set -A array -- "$var" ...
यदि आप गारंटी नहीं दे सकते हैं कि या के $var
साथ शुरू नहीं होगा ।-
+
- ऐरे सूचकांक शुरू होते हैं
0
।
- अलग-अलग सरणी तत्व के रूप में असाइन किए गए हैं
a[1]=value
।
- सरणियाँ विरल हैं। वह
a[5]=foo
काम करेगा भले ही a[0,1,2,3,4]
सेट न हो और उन्हें परेशान न करे।
${a[5]}
5 इंडिस के तत्व तक पहुंचने के लिए (जरूरी नहीं कि 6 वें तत्व अगर सरणी विरल है)। 5
किसी भी गणित अभिव्यक्ति हो सकता है।
- सरणी का आकार और सबस्क्रिप्ट सीमित है (4096 तक)।
${#a[@]}
सरणी में असाइन किए गए तत्व की संख्या है (सबसे बड़ा निर्दिष्ट इंडिस नहीं)।
- असाइन किए गए ग्राहकों की सूची जानने का कोई तरीका नहीं है (व्यक्तिगत रूप से 4096 तत्वों के परीक्षण के अलावा
[[ -n "${a[i]+set}" ]]
)।
$a
के रूप में ही है ${a[0]}
। यह है कि सरणियाँ किसी भी तरह अतिरिक्त मान देकर स्केलर चर का विस्तार करती हैं।
pdksh
और डेरिवेटिव (यह कई बीएसडी के ksh
और कभी-कभी sh
के लिए आधार है और ksh93 स्रोत मुक्त होने से पहले केवल ओपनसोर्स ksh कार्यान्वयन था):
ज्यादातर पसंद है ksh88
लेकिन ध्यान दें:
- कुछ पुराने कार्यान्वयन का समर्थन नहीं किया
set -A array -- foo bar
, ( --
वहाँ की जरूरत नहीं थी)।
${#a[@]}
एक प्लस सबसे बड़ा सौंपा सूचकांक का सूचकांक है। ( a[1000]=1; echo "${#a[@]}"
आउटपुट 1001 है, भले ही सरणी में केवल एक तत्व हो।
- नए संस्करणों में, सरणी आकार अब सीमित नहीं है (पूर्णांकों के आकार के अलावा)।
- के हाल के संस्करणों
mksh
से प्रेरित कुछ अतिरिक्त ऑपरेटरों है bash
, ksh93
या zsh
कार्य की तरह एक ला a=(x y)
, a+=(z)
, ${!a[@]}
सौंपा सूचकांक की सूची प्राप्त करने।
zsh
। zsh
सरणियों को आम तौर पर बेहतर तरीके से डिज़ाइन किया जाता है और सबसे अच्छा ksh
और csh
सरणियाँ लेते हैं। वे ksh
महत्वपूर्ण अंतर के साथ समान हैं :
- सूचकांक 1 पर शुरू होता है, 0 पर नहीं (
ksh
अनुकरण को छोड़कर ), यह बॉर्न सरणी (स्थिति पैरामीटर $ @, जो zsh
कि इसके $ argv सरणी के रूप में भी उजागर होता है) और csh
सरणियों के अनुरूप है ।
- वे सामान्य / स्केलर चर से एक अलग प्रकार हैं। ऑपरेटर उनके लिए अलग तरह से लागू होते हैं और जैसे आप आमतौर पर उम्मीद करते हैं।
$a
के रूप में ही नहीं है, ${a[0]}
लेकिन सरणी के गैर-खाली तत्वों ( "${a[@]}"
जैसे सभी तत्वों के लिए ksh
) में फैलता है ।
- वे सामान्य सरणियाँ हैं, विरल सरणियाँ नहीं।
a[5]=1
काम करता है, लेकिन सभी तत्वों को 1 से 4 तक खाली स्ट्रिंग प्रदान करता है यदि उन्हें असाइन नहीं किया गया है। तो ${#a[@]}
(के रूप में ${#a}
जो ksh में इंडिस 0 के तत्व का आकार है) सरणी में तत्वों की संख्या और सबसे बड़ा असाइन किया गया मसाला है।
- सहयोगी सरणियों का समर्थन किया जाता है।
- एरियर्स के साथ काम करने के लिए ऑपरेटरों की एक बड़ी संख्या का समर्थन किया गया है, यहां सूचीबद्ध करने के लिए बहुत बड़ा है।
- सरणियों के रूप में परिभाषित किया गया है
a=(x y)
। set -A a x y
यह भी काम करता है, लेकिन set -A a -- x y
जब तक ksh एमुलेशन ( --
zsh एमुलेशन में आवश्यक नहीं है) का समर्थन नहीं किया जाता है।
ksh93
। (यहाँ नवीनतम संस्करण का वर्णन करते हुए)। ksh93
, लंबे समय तक प्रायोगिक अब अधिक से अधिक सिस्टम में पाया जा सकता है कि अब इसे FOSS के रूप में जारी किया गया है। उदाहरण के लिए, यह /bin/sh
(जहां यह बॉर्न शेल को प्रतिस्थापित करता है /usr/xpg4/bin/sh
, पोसिक्स शेल अभी भी आधारित है ksh88
) और ksh
का Solaris 11
। इसके सरणियों का विस्तार और ksh88 है।
a=(x y)
एक सरणी को परिभाषित करने के लिए इस्तेमाल किया जा सकता है, लेकिन चूंकि a=(...)
इसका उपयोग यौगिक चर ( a=(foo=bar bar=baz)
) को परिभाषित करने के लिए भी किया जाता है , a=()
अस्पष्ट है और एक यौगिक नहीं, बल्कि एक यौगिक चर घोषित करता है।
- सरणियाँ बहु-आयामी हैं (
a=((0 1) (0 2))
) और सरणी तत्व भी यौगिक चर ( a=((a b) (c=d d=f)); echo "${a[1].c}"
) हो सकते हैं ।
- एक
a=([2]=foo [5]=bar)
बार में एक विरल सरणियों को परिभाषित करने के लिए एक वाक्यविन्यास का उपयोग किया जा सकता है।
- आकार सीमाएं हटा दी गईं।
- की सीमा तक नहीं
zsh
, लेकिन बड़ी संख्या में ऑपरेटरों ने सरणियों में हेरफेर करने के लिए समर्थन किया।
"${!a[@]}"
सरणी सूचकांकों की सूची पुनः प्राप्त करने के लिए।
- सहयोगी सरणियों को एक अलग प्रकार के रूप में भी समर्थन किया गया है।
bash
। bash
GNU परियोजना का खोल है। इसका उपयोग sh
OS / X के हाल के संस्करणों और कुछ GNU / Linux वितरणों के रूप में किया जाता है। bash
सरणियों ज्यादातर का अनुकरण ksh88
की कुछ सुविधाओं के साथ लोगों ksh93
और zsh
।
a=(x y)
समर्थित। समर्थित set -A a x y
नहीं है । a=()
एक खाली सरणी (कोई यौगिक चर नहीं bash
) बनाता है ।
"${!a[@]}"
सूचकांकों की सूची के लिए।
a=([foo]=bar)
सिंटैक्स समर्थित है और साथ ही कुछ अन्य से ksh93
और zsh
।
- हाल के
bash
संस्करण भी एक अलग प्रकार के रूप में सहयोगी सरणियों का समर्थन करते हैं।
yash
। यह अपेक्षाकृत हाल ही में, स्वच्छ, बहु-बाइट से अवगत पोसिक्स श कार्यान्वयन है। व्यापक उपयोग में नहीं। इसके एरे के समान एक और साफ एपीआई हैzsh
- सरणियाँ विरल नहीं हैं
- ऐरे सूचकांक 1 से शुरू होते हैं
- परिभाषित (और घोषित) के साथ
a=(var value)
array
अंतर्निहित तत्वों के साथ सम्मिलित, हटाए गए या संशोधित किए गए तत्व
array -s a 5 value
यदि उस तत्व को पहले से असाइन नहीं किया गया था, तो 5 वें तत्व को संशोधित करना विफल होगा।
- सरणी में तत्वों की संख्या है
${a[#]}
, ${#a[@]}
एक सूची के रूप तत्वों का आकार जा रहा है।
- सरणियाँ एक अलग प्रकार हैं।
a=("$a")
तत्वों को जोड़ने या संशोधित करने से पहले आपको एक स्केलर चर को फिर से परिभाषित करने की आवश्यकता है।
- जब आह्वान किया जाता है तो सरणियों का समर्थन नहीं किया जाता है
sh
।
तो, इससे आप देख सकते हैं कि सरणी समर्थन के लिए पता लगाना, जो आप कर सकते हैं:
if (unset a; set -A a a; eval "a=(a b)"; eval '[ -n "${a[1]}" ]'
) > /dev/null 2>&1
then
array_supported=true
else
array_supported=false
fi
उन सरणियों का उपयोग करने में सक्षम होने के लिए पर्याप्त नहीं है। आपको संपूर्ण और व्यक्तिगत तत्वों के रूप में सरणियों को निर्दिष्ट करने के लिए रैपर कमांड को परिभाषित करने की आवश्यकता होगी, और सुनिश्चित करें कि आप विरल सरणियों को बनाने का प्रयास नहीं करते हैं।
पसंद
unset a
array_elements() { eval "REPLY=\"\${#$1[@]}\""; }
if (set -A a -- a) 2> /dev/null; then
set -A a -- a b
case ${a[0]}${a[1]} in
--) set_array() { eval "shift; set -A $1"' "$@"'; }
set_array_element() { eval "$1[1+(\$2)]=\$3"; }
first_indice=0;;
a) set_array() { eval "shift; set -A $1"' -- "$@"'; }
set_array_element() { eval "$1[1+(\$2)]=\$3"; }
first_indice=1;;
--a) set_array() { eval "shift; set -A $1"' "$@"'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0;;
ab) set_array() { eval "shift; set -A $1"' -- "$@"'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0;;
esac
elif (eval 'a[5]=x') 2> /dev/null; then
set_array() { eval "shift; $1=("'"$@")'; }
set_array_element() { eval "$1[\$2]=\$3"; }
first_indice=0
elif (eval 'a=(x) && array -s a 1 y && [ "${a[1]}" = y ]') 2> /dev/null; then
set_array() { eval "shift; $1=("'"$@")'; }
set_array_element() {
eval "
$1=(\${$1+\"\${$1[@]}"'"})
while [ "$(($2))" -ge "${'"$1"'[#]}" ]; do
array -i "$1" "$2" ""
done'
array -s -- "$1" "$((1+$2))" "$3"
}
array_elements() { eval "REPLY=\${$1[#]}"; }
first_indice=1
else
echo >&2 "Array not supported"
fi
और फिर आप के साथ सरणी तत्वों का उपयोग "${a[$first_indice+n]}"
के साथ, पूरी सूची "${a[@]}"
और आवरण कार्यों का उपयोग ( array_elements
, set_array
, set_array_element
) (में एक सरणी के तत्वों की संख्या प्राप्त करने $REPLY
), एक पूरी या असाइन करने वाले तत्वों के रूप में देता है निर्धारित किया है।
शायद प्रयास के लायक नहीं। मैं perl
बॉर्न / POSIX शेल सरणी का उपयोग या सीमा करूँगा "$@"
:।
यदि आशय आंतरिक रूप से सरणियों का उपयोग करने वाले कार्यों को परिभाषित करने के लिए किसी उपयोगकर्ता के इंटरेक्टिव शेल द्वारा कुछ फ़ाइल रखने का इरादा है, तो यहां कुछ और नोट हैं जो उपयोगी हो सकते हैं।
आप स्थानीय स्कोप (फ़ंक्शन या अनाम फ़ंक्शंस में) zsh
सरणियों को अधिक कॉन्फ़िगर करने के लिए कॉन्फ़िगर कर सकते हैं ksh
।
myfunction() {
[ -z "$ZSH_VERSION" ] || setopt localoption ksharrays
# use arrays of indice 0 in this function
}
आप अनुकरण भी कर सकते हैं ksh
( ksh
सरणियों और कई अन्य क्षेत्रों के लिए अनुकूलता में सुधार )
myfunction() {
[ -z "$ZSH_VERSION" ] || emulate -L ksh
# ksh code more likely to work here
}
मन में है कि और आप के साथ हैं के लिए समर्थन छोड़ करने के लिए तैयार yash
है और ksh88
और के पुराने संस्करणों के pdksh
डेरिवेटिव, और जब तक आप विरल सरणियों बनाने की कोशिश नहीं करते हैं, तब तक आप लगातार उपयोग करने के लिए सक्षम होना चाहिए:
a[0]=foo
a=(foo bar)
(लेकिन नहीं a=()
)
"${a[#]}"
, "${a[@]}"
,"${a[0]}"
उन कार्यों में जो हैं emulate -L ksh
, जबकि zsh
उपयोगकर्ता अभी भी आम तौर पर zsh तरह से उसकी / उसकी सरणियों का उपयोग कर रहा है।