Bash中如何用case语句判断变量非空?求更优实现方案
问题场景
我在项目中使用case语句检查变量组合,原代码如下:
fun(){ case "$a:$b:$c" in *:*:*) echo fine;; *:2:*) echo ok;; 3:*:*) echo good;; *) echo not ok;; esac }
原本想用第一个分支*:*:*)判断变量$c非空,但该分支效果等同于末尾的*),当$c未设置时会误触发。我尝试过*:*:+和*:*:!''均无效,目前采用以下临时方案:
fun(){ c1=; [[ $c ]] && c1=1 case "$a:$b:$c1" in *:*:1) echo fine;; *:2:*) echo ok;; 3:*:*) echo good;; *) echo not ok;; esac }
想咨询是否有更优、更贴合case语法原生特性的实现方式?
优化实现方案
方案一:利用参数扩展构造匹配键(推荐)
直接借助shell的参数扩展特性,无需额外定义中间变量,完全贴合case原生逻辑:
fun(){ case "$a:$b:${c:+x}" in *:*:x) echo fine;; *:2:*) echo ok;; 3:*:*) echo good;; *) echo not ok;; esac }
${c:+x}的作用是:若$c非空(已设置且长度大于0),则替换为x;若$c未设置或为空,则替换为空字符串。这样第一个分支*:*:x就能精准匹配$c非空的场景,不会与默认分支冲突。
如果需要更清晰的标记,也可以用可读性更强的字符串,比如${c:+_non_empty_},效果完全一致。
方案二:调整分支顺序+通配符匹配
如果不想依赖参数扩展,可通过调整分支顺序,结合shell通配符实现:
fun(){ case "$a:$b:$c" in *:2:*) echo ok;; 3:*:*) echo good;; *:*:[![:space:]]*) echo fine;; *) echo not ok;; esac }
这里*:*:[![:space:]]*)表示最后一段包含至少一个非空白字符(即$c非空),但必须将该分支放在特定规则分支之后——因为case是按顺序匹配的,匹配到第一个符合的分支就会停止。注意:若$c全为空白字符,此方案会将其判定为空,若需要把全空白的$c视为非空,该方案不适用。
内容的提问来源于stack exchange,提问作者Ivan
相关产品推荐
相关产品推荐

