У меня есть два скалярных значения в виде столбцов:
% 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
в приведенный выше синтаксис ассоциации?
@MarkSetchell, что вы подразумеваете под /разобрать сами утверждения alias
/? И относитесь к cd ~
как к фиктивному примеру :-) Мой список псевдонимов довольно длинный.
Zsh имеет встроенную переменную aliases
, определенную как ассоциативную таблицу всех псевдонимов. Зачем самому делать стол...?
@SimonSmith идея состоит в том, чтобы проверить, какие псевдонимы я определил с помощью .zshrc
, и перечислить их с помощью цикла foreach по ассоциативной таблице.
Вы пытаетесь найти псевдонимы, созданные вами (т. е. не плагинами)?
Все еще не понимаю, почему вы делаете это вручную. Если вы хотите написать цикл, сканируя ~/.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
тем, что вы имеете в виду. И нет необходимости создавать ассоциативную таблицу... Если она вам нужна, создайте ее внутри цикла, добавив пары ключ-значение в пустой инициализированный ассоциативный массив.
@SimonSmith, прежде всего, спасибо. Во-вторых да, я пытаюсь найти псевдонимы, созданные мной. Чтобы прояснить ситуацию, я перефразирую свой вопрос, отделяя его от контекста псевдонимов.
Являются ли key
и val
уже массивами или просто строками, разделенными новой строкой?
строки с разделителями новой строки
Вам, вероятно, понадобится петля, но это не слишком грязно. Вы просто будете использовать две команды 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)
- создает ассоциативный массив из чередующихся ключей и значений.Интересно, я не думаю, что когда-либо замечал оператора почтового индекса раньше.
Не проще ли было бы разобрать сами утверждения
alias
? И какой смысл вcd ~
, а не в простомcd
?