この zsh for 構文はどういう意味ですか?

この zsh for 構文はどういう意味ですか?

私はドットファイルのソース管理に取り組んでいますが、私がやっていることの多くはザック・ホルマンのドットファイル彼がファイルでやっているように、すべての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出発点です。

まず、 2 行目に示すように、 はディレクトリの下にあるすべてのファイル$config_filesを含む配列であることに注意してください。.zsh$ZSHconfig_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ファイルシステムを何度も再帰的に検索するよりも高速です。 (for ループは他にもたくさんありますよね?)

その知識があれば、何ができるかは簡単にわかるはずです${${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

見た目より簡単ですよね?!;)

関連情報