パラメータ拡張にデフォルト値とalt_valueを使用すると、パラメータ値は削除されますか?

パラメータ拡張にデフォルト値とalt_valueを使用すると、パラメータ値は削除されますか?

私はBashに限られています。
パラメータを設定するかどうかに応じて、2つの文字列のいずれかをエコーし​​たいと思います。
例えば

if $ARG is notset|empty then print X
if $ARG is set&nonempty then print V

私は$ ARGコンテンツにまったく興味がありません。提供し、記入するかどうか。

IF/CASE/etcを介してこの結果が得られることがわかります。しかし、私はこの構造を何度も使用するので、単純に維持したいと思います。どのような方法でもこれを行い、関数でラップすることができることを知っていますが、スマートな方法(パラメータ拡張など)で作成できるかどうか疑問に思います。

私はすべて読んだhttps://tldp.org/LDP/abs/html/parameter-substitution.htmlそして、いくつかの同様のページで似ていて補完的なように見える2つのタスクを見つけました。

default value:      ${ARG:-X}
alternative value:  ${ARG:+V}

ちなみに、これは質問のタイトルから来たものです。:-空の場合はXを返し、空で:+ない場合はVを返します。

シンプル:

echo ${ARG:+V}${ARG:-X}

するほぼ私が望むもの。空または設定されていないX場合は$ARG印刷しますが、ARG = fooなどの他の場合はVfoo。これ:+は、:-私が望む方法で実際には補完的ではないからです${}${}:+

これを一度に実行し、引数の状態に応じて与えられた2つの値から選択し、実際には使用しないこのようなモンスター複合コマンドが必要になるようです(alt_valueと一緒に使用される${ARG:+V:-X}ため動作しません)。パラメーターが保持する実際のテキスト。:+V:-X

無邪気に入れ子にしようとしました。

echo ${${ARG:+V}:-X}

これは私にとって必要なものですが、Bashではうまくいきません。範囲拡張され、内部が${ARG:+V}パラメータではないため、外部が${}文句を言います。 (~コマンド置換は変数置換内にネストできますか?)

Vfoo私はそれを最初の文字に減らして問題を解決しようとすることができると思います。${xxx:0:1}しかし、それを行うには再び入れ子が必要なので、決して${${ARG:+V}${ARG:-X}:0:1}不可能です。

またはヘルパー変数の場合は問題ありません。

MINGW64 ~
$ f () { T=${1:+V}${1:-X} ; echo ${T:0:1} ; } ;

$ f "a"
V

$ f ""
X

$ f
X

これは私が望む動作を持つことができる最も近いものです。実際には、最初の文字を取得するためにランダムに長い
文字列を構成しているため、少し汚れています。T純粋な廃棄物。
また、一時変数を必要とせずにそれを式に圧縮したいと思いますT

Bashで何かを見逃しましたか?パラメータ拡張やその他の組み込みトリックを使用して、より良い方法でこの「選択」動作を取得できますか?

答え1

次のことができます。

either=(
  'value for unset or empty'
  'value for set and non-empty'
)
printf '%s\n' "${either[!!${#VAR}]}"

set +o histexpand(対話型bashを介して呼び出す場合は、履歴拡張()を無効にします。)

${#VAR}値の文字数に拡張されるのは、$VAR変数が空であるか設定されていない場合、算術式がゼロを生成し、そうでなければ1を生成するため、二重!!否定です。!!${#VAR}

を使用すると、zsh次のことができます。

print -r -- ${${var:+value for set and non-empty}:-value for unset or empty}

関連情報