Что означает этот zsh для синтаксиса?
Я работаю над источником, контролирующим мои точечные файлы, и большая часть того, что я делаю, основана на точечных файлах Зака Холмана. Я хочу получить исходные тексты всех файлов zsh, как он это делает в своих файлах, но прежде чем я просто добавлю туда код, я хочу на самом деле понять, что делает код. Фрагмент, с которым я запутался,
# all of our zsh files
typeset -U config_files
config_files=($ZSH/**/*.zsh)
# load the path files
for file in ${(M)config_files:#*/path.zsh}
do
source $file
done
# load everything but the path and completion files
for file in ${${config_files:#*/path.zsh}:#*/completion.zsh}
do
source $file
done
# initialize autocomplete here, otherwise functions won't be loaded
autoload -U compinit
compinit
# load every completion after autocomplete loads
for file in ${(M)config_files:#*/completion.zsh}
do
source $file
done
unset config_files
В основном я запутался в том, что здесь происходит
${(M)config_files:#*/path.zsh}
и здесь
${${config_files:#*/path.zsh}:#*/completion.zsh}
Так что все это значит?
1 ответ
PARAMETER EXPANSION
раздел zshexpn
Страница man - хорошая отправная точка.
Во-первых, давайте отметим, что $config_files
это массив, включающий все .zsh
файлы под $ZSH
каталог, как вы можете видеть во второй строке: config_files=($ZSH/**/*.zsh)
,
Этот синтаксис используется в строке ${(M)config_files:#*/path.zsh}
(обратите внимание, что M
внутри скобок это называется флагом расширения), это следующее:
${name:#pattern}
If the pattern matches the value of name, then substitute the
empty string; otherwise, just substitute the value of name.
If name is an array the matching array elements are removed
(use the `(M)' flag to remove the non-matched elements).
Другими словами, рассматриваемый цикл for повторяется по всем path.zsh
файлы в $ZSH. Вы могли бы использовать for file in $ZSH/**/path.zsh
как хорошо, но операция на $config_files
массив файлов работает быстрее, чем рекурсивный поиск файловой системы снова и снова. (Есть больше для цикла, не так ли?)
С этим знанием должно быть легко понять, что ${${config_files:#*/path.zsh}:#*/completion.zsh}
Сделаю. (Результат указан в комментарии так или иначе).
Я обычно использую несколько тривиальных примеров, чтобы лучше понять себя:
$ array=(foo bar baz)
$ print ${array}
foo bar baz
$ print ${array:#ba*}
foo
$ print ${(M)array:#ba*}
bar baz
Это проще, чем кажется, верно?! ;)