Как перебрать ассоциативные массивы в Bash

На основе ассоциативного массива в Bash script мне нужно перебрать его, чтобы получить ключ и значение.

#!/bin/bash

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

Я действительно не понимаю, как получить ключ при использовании цикла for-in.

Ответ 1

Доступ к ключам осуществляется с помощью восклицательного знака: ${!array[@]}, значения доступны с помощью ${array[@]}.

Вы можете перебирать пары "ключ/значение" следующим образом:

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

Обратите внимание на использование кавычек вокруг переменной в инструкции for (плюс использование @ вместо *). Это необходимо, если любые ключи содержат пробелы.

Путаница в другом ответе исходит из того, что ваш вопрос включает в себя "foo" и "bar" для ключей и значений.

Ответ 2

Вы можете получить доступ к клавишам с помощью ${!array[@]}:

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

Затем, итерация по парам ключ/значение проста:

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

Ответ 3

Используйте эту функцию более высокого порядка, чтобы предотвратить пирамиду гибели

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