Bashパラメータ拡張 - ハイフンをエスケープしながらプレフィックスを持つ変数を取得する

Bashパラメータ拡張 - ハイフンをエスケープしながらプレフィックスを持つ変数を取得する

編集する: 私はこの記事の重要な仮定を誤解したことに気づきました。構文は${!prefix@}関数名を取得できず、変数のみを取得できます。したがって、${!prefix@}アンダースコアがあっても関数名を返すことはできません。したがって、以下の太字の質問に対する私の答えはしっかりと「いいえ」です。 それにもかかわらず、以下のEdgarの答えは、特定のプレフィックスに基づいて関数名のリストを取得したい人に役立ちます。

元の質問

これBash パラメータ拡張マニュアル現在の環境で特定のプレフィックスで始まるすべての変数(非関数)のリストを取得する方法を提供します。

${!prefix@}

foo-たとえばfoo-setup、などで始まるいくつかの関数がありますfoo-runfoo-initialize今試してみましたが。${!foo-@}で始まる関数のリストを返すバリアントを取得できませんでしたfoo-${!foo\-@}私は、、、、、その他のさまざまなバリエーションを試しました"${!foo\-@}"。パラメータ拡張では、ハイフンが独自の意味を持っていることがわかっているため、一部のエスケープや類似なしでは機能しないと予想されます。しかし、私はまた、Bashが引数を拡張するなど、あらゆる状況で特殊文字をエスケープするためのメカニズムを持っている必要があると期待しています。ただし、ここではそうではないかもしれません。"${!foo-@}"bar=foo; ${!${bar}-@}-

(クロスプラットフォームの互換性が必要な場合は、ハイフンで連結された関数名を避けてください。。私はこれに同意します。また、アンダースコアの代わりにハイフンを使用して関数を入力する方がはるかに滑らかです...)

だから私は探求の精神でこのような質問を投げる。ハイフンプレフィックスで始まるすべての定義された関数(または通常は名前を参照)のリストを取得するためにデフォルトのパラメータ拡張を使用する方法はありますか?おそらく、解決策は私が知らない方法でハイフンを避けることです。

(そうでない場合は、変数の完全なリストを取得してから、必須のハイフン接頭辞を持つ変数のみを残すようにフィルタリングする方法はありますか?)

答え1

代替案はありますか?

declareはい、またはcompgen定義された関数のリストを取得するには、次のものを使用できます。

解決策1(指定された文字列/パターンを含む関数と一致)

declare -F | grep -o 'foo-.*'
#or
compgen -A function | grep 'foo-'

解決策2(具体的にはプレフィックス一致/特定の文字列/パターンで始まる)

declare -F | cut -d ' ' -f3 | grep '^foo-'
#or
compgen -A function | grep '^foo-'

パラメータ拡張の使用に関して関数名を取得することが可能かどうかはわかりません。マニュアルによると、変数でのみ動作するようです。

${!プレフィックス*}

${!プレフィックス@}

IFS特殊変数の最初の文字で区切られた名前は、プレフィックスで始まる変数名に展開されます。 「@」を使用して二重引用符内に拡張が発生すると、各変数名は別々の単語に展開されます。

そしてあなたが言ったこと:

もちろん、すべての関数の名前を変更してfoo-プレフィックスをfoo_に変更すると、${!foo_@}はすべての関数を取得します。

これを試してみて、効果があったのかと思います。 (私の考えではないようです。)いくつかの機能でテストしましたが、うまくいかなかったからです。

もちろん、ハイフンを使用して変数を定義することはできないため、orを-使用することは不可能です。${prefix-@}${prefix-*}

答え2

完全性のためにzshのパターンに一致する関数名のリストを取得するには、次のようにします。

typeset +f -m 'foo-*'

(これらの関数の定義も確認して+f置き換えてください)-f

ただし、zshの関数名は任意のバイトシーケンスにすることができます(最終的にはコマンドと同じ名前空間にあり、ファイルパスはnull以外のバイトのnull以外のシーケンスにすることができます)。したがって、出力は次のようになります。安定して後処理されていません。

しかし、パターンをキャプチャするk特別な連想配列の目を見ると、$functions配列のリストが得られます。M

foo_functions=( ${(Mk)functions:#foo-*} )

奇妙な名前を持つ関数の例:

$ typeset +f -m 'foo-*'
foo-a
b
c
foo-barbaz
$ print -rC1 -- ${(q)foo_functions}
foo-a$'\n'b$'\n'c
foo-bar$'\0'baz

関連情報