Есть ли способ создавать пары ключ-значение в сценарии 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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.