बैश शेल स्क्रिप्ट लूप से एरे इंडेक्स वेरिएबल वेरिएबल एक्सेस करना?


20

मैं अपने बैश शेल स्क्रिप्ट में एक सरणी को लूप करते हुए ऐरे इंडेक्स वेरिएबल को एक्सेस करना चाहता हूं।

myscript.sh
#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
for i in ${AR[*]}; do
  echo $i
done

उपरोक्त स्क्रिप्ट का परिणाम है:

foo
bar
baz
bat

परिणाम मैं चाहता हूँ:

0
1
2
3

इसे प्राप्त करने के लिए मैं अपनी स्क्रिप्ट को कैसे बदलूं?


7
यह भी ध्यान दें कि आप मूल रूप से "${array[*]}"इसके बजाय कभी नहीं चाहते हैं "${array[@]}"। अधिक या कम के *बजाय का उपयोग @यह एक सरणी के बजाय एक स्ट्रिंग के रूप में व्यवहार करता है।
जोर्डनम

जवाबों:


27

आप सरणी कुंजियों की सूची का उपयोग करके ऐसा कर सकते हैं । से bashआदमी पेज:

${!name[@]}
${!name[*]}

सरणी कुंजियों की सूची । यदि नाम एक सरणी चर है, तो नाम में निर्दिष्ट सरणी सूचकांकों (कुंजियों) की सूची में विस्तारित होता है। यदि नाम कोई सरणी नहीं है, 0तो नाम सेट है और अन्यथा शून्य है। जब @उपयोग किया जाता है और विस्तार दोहरे उद्धरण चिह्नों के भीतर दिखाई देता है, तो प्रत्येक कुंजी एक अलग शब्द में फैल जाती है।

अपने उदाहरण के लिए:

#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
for i in "${!AR[@]}"; do
  printf '${AR[%s]}=%s\n' "$i" "${AR[i]}"
done

इसका परिणाम यह होगा:

${AR[0]}=foo
${AR[1]}=bar
${AR[2]}=baz
${AR[3]}=bat

ध्यान दें कि यह गैर-क्रमिक सूचकांक के लिए भी काम करता है:

#!/bin/bash
AR=([3]='foo' [5]='bar' [25]='baz' [7]='bat')
for i in "${!AR[@]}"; do
  printf '${AR[%s]}=%s\n' "$i" "${AR[i]}"
done

इसका परिणाम यह होगा:

${AR[3]}=foo
${AR[5]}=bar
${AR[7]}=bat
${AR[25]}=baz

1
यद्यपि यह उत्तर वांछित परिणाम को पूरा करता है, यह प्रिंटफ स्टेटमेंट द्वारा अनावश्यक रूप से बाधित है। उदाहरण के लिए: printf "$i=(${AR[i]})\n"या echo "$i=(${ARi]})"दोनों कुंजी और संस्करण प्राप्त करने के तरीके को दिखाते हुए थोड़ा अतिरिक्त देते हैं लेकिन सख्ती से बोलने echo "$i"से ओपी का जवाब होगा। बाकी "बैश फू" :)
डाइमेक

5

जोर्डनम के उत्तर के अतिरिक्त आप इसमें एक Cलूप की तरह भी कर सकते हैं bash:

for ((idx=0; idx<${#array[@]}; ++idx)); do
    echo "$idx" "${array[idx]}"
done

1

आप ऐसा कुछ कर सकते हैं:

#!/bin/bash
AR=('foo' 'bar' 'baz' 'bat')
length=${#AR[@]}
for (( i = 0; i < length; i++ )); do
  echo "$i"
done

उत्पादन:

0
1
2
3

1
यह क्या कहता है कि  pfnuesel का जवाब   पहले से ही नहीं कहता है?
जी-मैन का कहना है कि 'मोनिका'

मुझसे गलती हो सकती है लेकिन क्या pfnuesels प्रत्येक पुनरावृत्ति पर सरणी की लंबाई का पुन: मूल्यांकन नहीं करता है?
क्रिस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.