Есть ли способ создавать пары ключ-значение в сценарии Bash?

82

Я пытаюсь создать словарь пары ключ-значение с помощью сценария Bash. Я пытаюсь использовать эту логику:

declare -d dictionary
defaults write "$dictionary" key -string "$value"

... где $dictionaryпеременная, но это не работает.

Есть ли способ создавать пары ключ-значение в сценарии Bash?

РКС
источник
я работал над bash. Придумал способ сделать это сам.
RKS
использование этого также помогает: urls + = ('<dict> <key> key1 </key> <string>' $ value1 '</string> <key> key2 </key> <string>' $ value2 '</ string > <key> key3 </key> <string> '$ value3' </string> </dict> '
RKS
3
Большой! Вам разрешено (и даже поощряется) отвечать на свои вопросы в StackOverflow, таким образом вы помогаете другим в подобной ситуации.
Johnsyweb
Я поддержу ваш ответ, если вы включите некоторые примеры использования и вывода. Удачи.
shellter

Ответы:

154

В bash версии 4 были введены ассоциативные массивы.

declare -A arr

arr["key1"]=val1

arr+=( ["key2"]=val2 ["key3"]=val3 )

Теперь массив arr содержит три пары значений ключа. Bash довольно ограничен в том, что вы можете с ними делать, без сортировки, извлечения и т. Д.

for key in ${!arr[@]}; do
    echo ${key} ${arr[${key}]}
done

Будет перебирать все ключевые значения и выводить их эхом.

Примечание. Bash 4 не входит в состав Mac OS X из-за лицензии GPLv3; вам нужно скачать и установить его. Подробнее об этом см. Здесь

петеши
источник
25
Важно отметить, что Bash 4 не поставляется с Mac OS X из-за его лицензии GPLv3; вам нужно скачать и установить его. (Apple по-прежнему
выпускает
5
Здесь есть минус: итерация не упорядочена по порядку вставки.
AlikElzin-kilaka
определенно нужен bash версии 4. В противном случае объявление -A не сработает. Mac поставляется с bash 3.2
Мамун
2
Это не из-за лицензии GPLv3, а потому, что Apple не хочет использовать лицензионное программное обеспечение GPLv3. Так что в лицензии GPLv3 нет ничего плохого, но, полагаю, что-то не так с Apple.
Tech Nomad
32

Если вы можете использовать простой разделитель, очень простой одинарный разделитель будет следующим:

for i in a,b c_s,d ; do 
  KEY=${i%,*};
  VAL=${i#*,};
  echo $KEY" XX "$VAL;
done

При этом iзаполняется последовательностями символов, такими как "a,b"и "c_s,d". каждый разделен пробелами. После doмы используем подстановку параметров, чтобы извлечь часть перед запятой ,и часть после нее.

математика
источник
Не могли бы вы объяснить приведенный вами пример?
AlikElzin-kilaka
Вопрос: Будет ли работать, если bпеременная содержит пробелы?
AlikElzin-kilaka
в моем примере b не является переменной и не будет работать, поскольку список для цикла for разделен пробелами.
math
2

Для постоянного хранения ключей / значений вы можете использовать kv-bashчистую реализацию bash базы данных ключ / значение, доступную по адресу https://github.com/damphat/kv-bash

Применение

git clone https://github.com/damphat/kv-bash
source kv-bash/kv-bash

Попробуйте создать несколько постоянных переменных

kvset myName  xyz
kvset myEmail xyz@example.com

#read the varible
kvget myEmail

#you can also use in another script with $(kvget keyname)
echo $(kvget myEmail)
андрей
источник
2

В bash мы используем

declare -A name_of_dictonary_variable

чтобы Баш понял, что это словарь.

Например, вы хотите создать soundsсловарь,

declare -A sounds

sounds[dog]="Bark"

sounds[wolf]="Howl"

где dogи wolfесть "keys", и Barkи Howlесть "values".

Вы можете получить доступ ко всем значениям, используя: echo ${sounds[@]}ИЛИecho ${sounds[*]}

Вы можете получить доступ ко всем ключам, только используя: echo ${!sounds[@]}

И если вам нужно какое-либо значение для определенного ключа, вы можете использовать:

${sounds[dog]}

это даст вам value ( Bark) для key ( Dog).

Ручир Диксит
источник
0

в более старом bash (или в sh), который не поддерживает declare -A, можно использовать следующий стиль для имитации ключа / значения

# key
env=staging


# values
image_dev=gcr.io/abc/dev
image_staging=gcr.io/abc/stage
image_production=gcr.io/abc/stable

img_var_name=image_$env

# active_image=${!var_name}
active_image=$(eval "echo \$$img_var_name")

echo $active_image
Роман
источник