zshパラメーター拡張代替モードは、入力がインライン以外の変数の場合、文字列を異なる方法で解析します。

zshパラメーター拡張代替モードは、入力がインライン以外の変数の場合、文字列を異なる方法で解析します。

zshパラメーター拡張代替モードは、入力がインライン変数ではなく変数の場合、文字列を異なる方法で解析します。

これはキャラクターエスケープと関係があると思いますが、それを修正する方法がわかりません。

以下のコードでは、>*2.5.8printf出力でフィルタリングする必要があります。これは変数の最初の引数拡張を使用して発生しますversions

ただし、curl呼び出しがインラインの場合、上記の3つの値はフィルタリングされません。

呼び出しをインライン化curlしながら3つの値をフィルタリングするにはどうすればよいですか?

#!/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:]]##}}

答え1

見積もりの$(command)​​交換:

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:]]##}

${}(上記から削除されたexpnの周りに重複重複があります)


基本zshシェルではパラメータ拡張分裂を避けるために引用は必要ありませんIFS(しかし、それでも悪いことはありません)。引用なしコマンドの置き換え分割されるので、IFSこれを防ぐために引用する必要があります。

手動zshexpn(1):

PARAMETER EXPANSION

SH_WORD_SPLIT特に、このオプションが設定されていないと、引用符を持たない引数の単語は自動的にスペースに分割されません。詳細については、以下のこのオプションの参照を参照してください。これは他のシェルとの重要な違いです。ただし、他のシェルと同様に、引用符のないパラメータ拡張ではスペースは無視されます。

COMMAND SUBSTITUTION

代替項目を二重引用符で囲んでいない場合、引数は出力を単語に分割するために使用されますIFS


また、次のようにこれらの文字列を削除する別の方法があります。

printf -- '%s\n' ${${=versions}:#([*+>-]|2.5.8)}

引用符なしでコマンド置換と組み合わせて使用​​できます。

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)}

上記はフォーマットパラメータ拡張を使用します${name:#pattern}。このマニュアルには次のように記載されています。

${name:#pattern}パターンが名前の値と一致する場合は空の文字列に置き換え、それ以外の場合は単に名前の値を置き換えます。 name が配列の場合、一致する配列要素が削除されます。(M)一致しない要素を削除するには、このフラグを使用してください。

関連情報