Если вы доверяете выводу вашей команды rhc, вы можете просто получить его:
. <(rhc env list -a <app-name>)
Это приведет к тому, что источник (выполнит )каждую строку, созданную rhc
.
Как написано выше, код определяет переменные, но не экспортирует их. Мы могли бы это исправить, но приведенный ниже код безопаснее и выполняет экспорт.
Исходная команда .
ожидает файл в качестве аргумента. Чтобы преобразовать вывод rhc
в файл -, подобный объекту, мы используем подстановку процесса:<(...)
.
Для большей безопасности используйте:
while read -r line; do declare -x "$line"; done < <(rhc env list -a <app-name>)
Здесь мы используем подстановку процесса, <(...)
, в сочетании с перенаправлением ввода, <
, так что цикл while
считывает вывод rhc
. Пространство между первым и вторым <
необходимо, :не не его опускают.
Опция -x
для declare
указывает bash экспортировать переменную.
В соответствии с комментарием ниже, команду rhc
можно поместить в строку над циклом while
через:
tmpvar=$(rhc env list -a <app-name>)
while read -r line; do declare -x "$line"; done <<<"$tmpvar"
<<<
создает здесь строку . В данном случае это означает, что $tmpvar
предоставляется как вход для цикла while
.
Оболочка zsh
(отмечает, что zsh
имел поддержку ассоциативных массивов за десятилетия до того, какbash
)имел операторы для этого:
${hash[(R)pattern]}
расширяется до значений , соответствующих шаблону. ${(k)hash[(R)pattern]}
расширяется до клавиш, где соответствующее значение соответствует шаблону. ${(k)hash[(Re)string]}
То же самое, за исключением того, что строка обрабатывается как e
строка xact, а не шаблон, даже если она содержит подстановочные знаки. Так:
print -r -- ${(k)array[(Re)red]}
Будут напечатаны не -пустые ключи со значением red
.
Чтобы включить пустые ключи, используйте:
$ typeset -A array
$ array=(a blue b red c yellow '' red)
$ printf '<%s>\n' "${(@k)array[(Re)red]}"
<>
<b>
Это некрасиво, но можно:
for k in "${!array[@]}"; do
[[ ${array[$k]} == red ]] && printf '%s\n' "$k"
done
Это будет перебирать индексы массива и проверять каждый, если их значение равно red
, если да, то будет напечатан индекс.
В качестве альтернативы и тоже некрасиво можно было бы использоватьsed
:
declare -p array | sed -n 's/.*\[\(.*\)\]="red".*/\1/p'
Это напечатает массив, как объявлено, и найдет индекс для значения red
и распечатает его.
Предположим, что вы хотите получить список ключей, соответствующих определенному значению, и хотите сохранить этот список в массиве:
#!/bin/bash
declare -A hash
hash=(
[k1]="hello world"
[k2]="hello there"
[k3]="hello world"
[k4]=bumblebees
)
string="hello world"
keys=()
for key in "${!hash[@]}"; do
if [[ ${hash[$key]} == "$string" ]]; then
keys+=( "$key" )
fi
done
printf 'Keys with value "%s":\n' "$string"
printf '\t%s\n' "${keys[@]}"
Это просматривает список ключей и проверяет значение, соответствующее каждому ключу, на соответствие строке, которую мы ищем. Если есть совпадение, мы сохраняем ключ в массиве keys
.
В конце выводятся найденные ключи.
Вывод этого скрипта будет
Keys with value "hello world":
k1
k3