在 case 中转换 if 语句

在 case 中转换 if 语句

我目前正在测试脚本中的更改以提高性能。具体来说,我想更改ifcase语句。

然而,作为 shell 编程的新手,我陷入了这种类型的声明中:

if [ "$A" == "x" -a "$B" == "y" ] 
    then
        let a=a+1
fi 

我尝试了这个但没有成功:

case "$A$B" in
    "x""y") let a=a+1
;;
esac

我做错了什么?

是否可以在 case 语句中管理“!=”?例如:

if [ "$A" == "x" -a "$B" != "y" ] 
then
    let a=a+1
fi 

答案1

你的case例子对我有用,但请注意,你正在比较级联A,因此如果is和为空B,则模式也将匹配。 (我认为中间的双引号是多余的。)只需要一个AxyBcase单词与模式进行比较,因此除非通过连接,否则无法比较多个变量。

在标准test, or[命令中,比较运算符是===适用于某些系统,但并非全部。此外,使用组合条件-a是有问题的,至少对于诸如 之类的条件是这样-n。 (看这个问题)。更好地使用if [ "$A" = x ] && [ "$B" = y ] ; then ...

至于反转 a case,您需要想出一个匹配除目标字符串之外的所有内容的模式。extglob在重击中其他允许匹配除以下内容之外的任何内容:

case $B in !(y) ) echo not y ;; esac

如果没有它,您需要做更多的工作来反转模式,或者使用多个模式,第一个模式与字符串匹配,稍后的默认匹配执行实际操作。

case $B in ??*) echo not y ;; [^y]) echo also not y ;; esac

case $B in y) ;; *) echo still not y ;; esac

(没有保证,尤其是第一个。坦率地说,这样做的整个想法似乎很糟糕。)

无论如何,既然您提到了性能原因,您可能会考虑更改为 Perl 或 Python 而不是 shell,不是因为简单的比较,而是因为它们允许您在不调用外部程序(例如grepsedcutjq)的情况下执行更多操作。另外,性能优化的第一条规则:衡量差异。

答案2

#  $A = "x" && $B = "y"
case ${A:--}/${B:--} in 'x/y' ) let a=a+1;; esac

# $A = "x" && $B != "y"
case $A in 'x' ) case $B in '' | ??* | [!y] ) let a=a+1;; esac;; esac

相关内容