Was bedeutet diese zsh-Syntax?

Was bedeutet diese zsh-Syntax?

Ich arbeite an der Quellcodeverwaltung meiner Dotfiles und vieles von dem, was ich mache, basiert aufZach Holmans Dotfiles. Ich möchte alle zsh-Dateien als Quelle verwenden, so wie er es in seinen Dateien tut, aber bevor ich den Code einfach dort hineinwerfe, möchte ich wirklich verstehen, was der Code macht. Der Codeausschnitt, der mich verwirrt, ist

# 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

Vor allem bin ich verwirrt, was hier passiert

${(M)config_files:#*/path.zsh}

und hier

${${config_files:#*/path.zsh}:#*/completion.zsh}

Was bedeutet das alles?

Antwort1

Der PARAMETER EXPANSIONAbschnitt der zshexpnManpage ist ein guter Ausgangspunkt.

Beachten Sie zunächst, dass $config_fileses sich um ein Array handelt, das alle .zshDateien im $ZSHVerzeichnis enthält, wie Sie in der zweiten Zeile sehen können: config_files=($ZSH/**/*.zsh).

Diese in der Zeile verwendete Syntax ${(M)config_files:#*/path.zsh}(bitte beachten Sie, dass Minnerhalb der Klammern einErweiterungsflagge) ist das Folgende:

${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).

Mit anderen Worten, die betreffende For-Schleife durchläuft alle path.zshDateien in $ZSH. Sie könnten for file in $ZSH/**/path.zshauch verwenden, aber die Operation auf dem $config_filesDateiarray ist schneller, als das Dateisystem immer wieder rekursiv zu durchsuchen. (Es gibt noch mehr For-Schleifen, oder nicht?)

Mit diesem Wissen sollte es einfach sein, herauszufinden, was ${${config_files:#*/path.zsh}:#*/completion.zsh}passieren wird. (Das Ergebnis wird ohnehin im Kommentar angegeben.)


Ich verwende normalerweise einige triviale Beispiele, um selbst ein besseres Verständnis zu bekommen:

$ array=(foo bar baz)
$ print ${array}
foo bar baz
$ print ${array:#ba*}
foo
$ print ${(M)array:#ba*}
bar baz

Es ist einfacher, als es aussieht, oder?!;)

verwandte Informationen