बैश में साहचर्य सरणियों पर पुनरावृति कैसे करें


351

एक बैश स्क्रिप्ट में एक साहचर्य सरणी के आधार पर, मुझे कुंजी और मूल्य प्राप्त करने के लिए उस पर पुनरावृति करने की आवश्यकता है।

#!/bin/bash

declare -A array
array[foo]=bar
array[bar]=foo

मैं वास्तव में फॉर-लूप का उपयोग करते समय कुंजी प्राप्त करने का तरीका नहीं समझता।


14
$ घोषित करें- सरणी = ([foo] = बार [बार] = फू) # प्रारंभिक एक ही बार में
ऐनिसबेट

3
प्रमुख मूल्यों की एक छोटी सूची के लिए आप इस पर विचार कर सकते हैं:for i in a,b c_s,d ; do KEY=${i%,*}; VAL=${i#*,}; echo $KEY" XX "$VAL; done
गणित

जवाबों:


582

कुंजी एक विस्मयादिबोधक बिंदु का उपयोग करके पहुँचा रहे हैं: ${!array[@]}, मूल्यों का उपयोग कर पहुंचा जा सकता है ${array[@]}

आप इस तरह से कुंजी / मान जोड़े पर पुनरावृति कर सकते हैं:

for i in "${!array[@]}"
do
  echo "key  : $i"
  echo "value: ${array[$i]}"
done

forकथन में चर के आसपास उद्धरणों के उपयोग पर ध्यान दें (साथ ही @इसके बजाय उपयोग *)। किसी भी कुंजी में रिक्त स्थान शामिल होने की स्थिति में यह आवश्यक है।

दूसरे उत्तर में भ्रम इस तथ्य से आता है कि आपके प्रश्न में कुंजी और मान दोनों के लिए "फू" और "बार" शामिल हैं।


3
यह अब है अगर एक सरणी के लिए सभी कुंजी असाइन करें:array=(${!hash[@]})
माइकल-ओ

12
@ माइकल-ओ: आपको व्हाट्सएप हो सकने वाली चाबियों की सुरक्षा के लिए पैरामीटर विस्तार को उद्धृत करना होगा:array=("${!hash[@]}")
आगे की सूचना तक रोक दिया गया।

@ डेनिसविलियम्सन, बहुत बहुत धन्यवाद। मेरे दिमाग में यह नहीं था।
माइकल-ओ

हम एक चर के बजाय एक फ़ंक्शन तर्क संख्या का उपयोग कैसे कर सकते हैं? जैसे for i in "${!$1[@]}"?
pkaramol

2
@pkaramol: बैश 4.3 में शुरू होकर आप namerefs का उपयोग कर सकते हैं। उदाहरण: declare -A aa; aa['A']=a1; aa['B']=b2; aa['C']=c3; foo () { declare -n assoc=$1; for key in "${!assoc[@]}"; do echo "Key: $key; Value: ${assoc[$key]}"; done; }; foo aa। कृपया कुछ महत्वपूर्ण जानकारी के लिए BashFAQ / 006 देखें।
अगली सूचना तक रोक दिया गया।

42

आप के साथ कुंजी का उपयोग कर सकते हैं ${!array[@]}:

bash-4.0$ echo "${!array[@]}"
foo bar

फिर, कुंजी / मूल्य जोड़े पर पुनरावृत्ति करना आसान है:

for i in "${!array[@]}"
do
  echo "key :" $i
  echo "value:" ${array[$i]}
done

1
मैने िकया "!" - ध्यान भी नहीं दिया, कोई नहीं था, क्षमा करें .. :)
pex

8

कयामत के पिरामिड को रोकने के लिए इस उच्च क्रम फ़ंक्शन का उपयोग करें

foreach(){ 
  arr="$(declare -p $1)" ; eval "declare -A f="${arr#*=}; 
  for i in ${!f[@]}; do $2 "$i" "${f[$i]}"; done
}

उदाहरण:

$ bar(){ echo "$1 -> $2"; }
$ declare -A foo["flap"]="three four" foo["flop"]="one two"
$ foreach foo bar
flap -> three four
flop -> one two

1
मुझे यकीन नहीं है कि यह कैसे लागू होता है? कयामत का पिरामिड एक विशुद्ध रूप से सौंदर्य का मुद्दा नहीं है और वास्तव में केवल वस्तु-उन्मुख भाषाओं में लागू होता है?
अलेक्सेज मगुरा

1
क्या आप इसे समझा सकते हैं? फ़ॉर्चर फ़ंक्शन थोड़ा मुश्किल है। मुझे नहीं मिला।
बैलिंट स्ज़ेगेटी

-1
declare -a arr
echo "-------------------------------------"
echo "Here another example with arr numeric"
echo "-------------------------------------"
arr=( 10 200 3000 40000 500000 60 700 8000 90000 100000 )

echo -e "\n Elements in arr are:\n ${arr[0]} \n ${arr[1]} \n ${arr[2]} \n ${arr[3]} \n ${arr[4]} \n ${arr[5]} \n ${arr[6]} \n ${arr[7]} \n ${arr[8]} \n ${arr[9]}"

echo -e " \n Total elements in arr are : ${arr[*]} \n"

echo -e " \n Total lenght of arr is : ${#arr[@]} \n"

for (( i=0; i<10; i++ ))
do      echo "The value in position $i for arr is [ ${arr[i]} ]"
done

for (( j=0; j<10; j++ ))
do      echo "The length in element $j is ${#arr[j]}"
done

for z in "${!arr[@]}"
do      echo "The key ID is $z"
done
~
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.