Ein Zsh-Parametererweiterungs-Ersetzungsmuster analysiert Zeichenfolgen anders, wenn die Eingabe eine Variable statt einer Inline-Eingabe ist.
Ich nehme an, dass es etwas mit der Zeichenflucht zu tun hat, bin mir aber nicht sicher, wie ich das umgehen kann.
Im folgenden Code sollen >
, *
& 2.5.8
aus der printf-Ausgabe herausgefiltert werden, die bei der ersten Parametererweiterung mit der Variable auftritt versions
.
Wenn der curl
Aufruf jedoch integriert ist, werden die obigen drei Werte nicht herausgefiltert.
Wie kann ich den curl
Aufruf integrieren und trotzdem die drei Werte herausfiltern?
#!/usr/bin/env zsh
setopt EXTENDED_GLOB
# variable: 3 values are correctly filtered out
versions=$(curl '--silent' '--location' 'https://api.sdkman.io/2/candidates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8')
printf -- '%s\n' ${${(Z+n+)versions//[*+>][ *+>]# [[:graph:]]##}}
# inlined: 3 values are not filtered out
printf -- '%s\n' ${${(Z+n+)$(curl '--silent' '--location' 'https://api.sdkman.io/2/candidates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8')//[*+>][ *+>]# [[:graph:]]##}}
Antwort1
Zitieren Sie die $(command)
Ersetzung:
printf -- '%s\n' ${(Z+n+)"$(curl '--silent' '--location' 'https://api.sdkman.io/2/candidates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8')"//[*+>][ *+>]# [[:graph:]]##}
(Es gab einen zusätzlichen unnötigen Eintrag ${}
rund um den Expn, der oben entfernt wurde)
In einer Standard zsh
-ShellParametererweiterungmuss nicht in Anführungszeichen gesetzt werden, um eine Aufteilung durch zu vermeiden IFS
(aber es schadet auch nicht). Nicht in AnführungszeichenBefehlsersetzungunterliegt der Aufteilung durch IFS
, daher muss dies durch Anführungszeichen vermieden werden.
Das Handbuch zshexpn(1)
:
PARAMETER EXPANSION
Beachten Sie insbesondere, dass Wörter von Parametern ohne Anführungszeichen nicht automatisch an Leerzeichen getrennt werden, es sei denn, die Option
SH_WORD_SPLIT
ist gesetzt; weitere Einzelheiten finden Sie weiter unten in den Verweisen auf diese Option. Dies ist ein wichtiger Unterschied zu anderen Shells. Wie in anderen Shells werden jedoch Nullwörter aus den Erweiterungen von Parametern ohne Anführungszeichen ausgelassen.
COMMAND SUBSTITUTION
Wenn die Ersetzung nicht in Anführungszeichen eingeschlossen ist, wird die Ausgabe mithilfe des
IFS
Parameters in Wörter aufgeteilt.
Es gibt möglicherweise auch andere Möglichkeiten, diese Zeichenfolgen zu entfernen, z. B.
printf -- '%s\n' ${${=versions}:#([*+>-]|2.5.8)}
die mit einer nicht in Anführungszeichen gesetzten Befehlsersetzung verwendet werden könnte:
printf -- '%s\n' ${$(curl '--silent' '--location' 'https://api.sdkman.io/2/candi'\
'dates/groovy/darwin/versions/list?current=2.5.8&installed=2.5.8'):#([*+>-]|2.5.8)}
Oben wird eine Parametererweiterung in der Form verwendet ${name:#pattern}
. Im Handbuch steht:
${name:#pattern}
Wenn das Muster mit dem Wert von name übereinstimmt, ersetzen Sie es durch die leere Zeichenfolge. Andernfalls ersetzen Sie es einfach durch den Wert von name. Wenn name ein Array ist, werden die übereinstimmenden Array-Elemente entfernt (verwenden Sie das(M)
Flag, um die nicht übereinstimmenden Elemente zu entfernen).