Zsh в MacOS: как создать ассоциативный массив (хеш-таблицу) из двух скаляров, похожих на столбцы?

У меня есть два скалярных значения в виде столбцов:

% echo $key
hom
doc
fam

echo $val
'home'
'Documents'
'Family'

и я хочу создать из них ассоциативный массив.

Я знаю о методе создания ассоциативного массива, как показано ниже:

declare -A my_assoc_arr
my_assoc_arr=(hom home doc Documents fam Family)

Но какой самый простой способ создать ассоциативный массив, переваривая $key и $val в том виде, в каком они у меня есть (скалярные, столбчатые)? Есть ли какой-либо другой синтаксис ассоциации, или мне нужно приложить усилия, чтобы перетасовать $key и $val в приведенный выше синтаксис ассоциации?

Не проще ли было бы разобрать сами утверждения alias? И какой смысл в cd ~, а не в простом cd?

Mark Setchell 29.01.2023 12:28

@MarkSetchell, что вы подразумеваете под /разобрать сами утверждения alias/? И относитесь к cd ~ как к фиктивному примеру :-) Мой список псевдонимов довольно длинный.

user1146081 29.01.2023 12:56

Zsh имеет встроенную переменную aliases, определенную как ассоциативную таблицу всех псевдонимов. Зачем самому делать стол...?

Simon Smith 29.01.2023 13:18

@SimonSmith идея состоит в том, чтобы проверить, какие псевдонимы я определил с помощью .zshrc, и перечислить их с помощью цикла foreach по ассоциативной таблице.

user1146081 29.01.2023 14:06

Вы пытаетесь найти псевдонимы, созданные вами (т. е. не плагинами)?

Simon Smith 29.01.2023 15:04

Все еще не понимаю, почему вы делаете это вручную. Если вы хотите написать цикл, сканируя ~/.zshrc, вы можете попробовать awk '/^\s*alias\s/ {sub(/^\s*alias/,""); sub(/=/,"\n"); print $0}' ~/.zshrc | while IFS=' ' read -r k; do IFS= read -r v; printf '%s:%s\n' "$k" "$v"; done. Замените команду printf тем, что вы имеете в виду. И нет необходимости создавать ассоциативную таблицу... Если она вам нужна, создайте ее внутри цикла, добавив пары ключ-значение в пустой инициализированный ассоциативный массив.

Simon Smith 29.01.2023 15:09

@SimonSmith, прежде всего, спасибо. Во-вторых да, я пытаюсь найти псевдонимы, созданные мной. Чтобы прояснить ситуацию, я перефразирую свой вопрос, отделяя его от контекста псевдонимов.

user1146081 29.01.2023 15:33

Являются ли key и val уже массивами или просто строками, разделенными новой строкой?

chepner 29.01.2023 15:50

строки с разделителями новой строки

user1146081 29.01.2023 15:51
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
9
70
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вам, вероятно, понадобится петля, но это не слишком грязно. Вы просто будете использовать две команды read для одновременного чтения строки из каждой строки.

typeset -A arr

while IFS= read -u 3 -r k
      IFS= read -u 4 -r v
do
    arr[$k]=$v
done 3<<< $key 4<<< $val

Первый read читает из дескриптора файла 3 (который перенаправляется из строки здесь, созданной из $key, второй из дескриптора файла 4 (аналогично перенаправляется из $val).

$ typeset -p arr
typeset -A arr=( [doc]=Documents [fam]=Family [hom]=home )

(Это предполагает, что key и val имеют одинаковое количество строк. Я не хочу спускаться в кроличью нору, имея дело с альтернативой, которая заставляет вас решать, что делать с оставшимися ключами или значениями.)

В zsh вы также можете использовать оператор «zip», чтобы перетасовать два стандартных массива в упомянутый вами синтаксис ассоциативного массива:

typeset -a keys=("${(f@)key}") vals=("${(f@)val}")
typeset -A arr=("${(@)keys:^vals}")

Некоторые из частей:

  • ${f)...} — использует флаг расширения параметра f для разделения строки на новые строки.
  • "${(@)...}" - обеспечивает обработку пустых значений и значений с пробелами (вероятно, здесь это не обязательно).
  • ${...:^...} — объединяет два массива вместе, чередуя значения из каждого массива. Результирующий массив будет в два раза длиннее самого короткого входного массива.
  • typeset -A arr=(k1 v1 k2 v2) - создает ассоциативный массив из чередующихся ключей и значений.

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

chepner 29.01.2023 17:42

Другие вопросы по теме