使用 default 和 alt_value 进行参数扩展,会丢弃参数值吗?

使用 default 和 alt_value 进行参数扩展,会丢弃参数值吗?

我仅限于 Bash。
我想回显两个字符串之一,具体取决于是否设置了参数。
比方说

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

我对 $ARG 内容完全不感兴趣。无论是否提供和填写。

我知道我可以通过 IF/CASE/等得到这个结果。但我会多次使用这个结构,并且我想保持简洁。我知道我可以用任何方式做到这一点并将其包装到一个函数中,但我很好奇是否可以用某种智能方式(即参数扩展)来制作它?

我已读完https://tldp.org/LDP/abs/html/parameter-substitution.html和一些类似的页面,我注意到有两个类似的、看似互补的操作:

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

顺便说一下,这就是问题标题的来源。:-空时返回 X,:+非空时返回 V。

一个简单的:

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

几乎我想要的是。X$ARG为空或未设置时打印出,但在任何其他情况下,例如 ARG=foo,它都会打印出Vfoo。那是因为:+:-并不是我想要的真正互补的方式;)为了让它像简单的串联一样工作,${}${}我需要一个“逆”,:+当空时输出“默认”,或者不输出任何内容(不是:测试的变量)。

似乎我需要一些像这样的怪物复合命令${ARG:+V:-X}(它不起作用,因为它与 alt_value:+一起使用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!!是双重否定,!!${#VAR}因为如果变量为空或未设置,则算术表达式生成 0,否则生成 1。

使用zsh,您可以执行以下操作:

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

相关内容