Преобразование if в случае

В настоящее время я тестирую изменения в своих сценариях для повышения производительности. В частности, я хочу изменить, if к утверждениям case .

Однако, будучи новичком в программировании оболочки, я зацикливаюсь на этом типе утверждения:

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

Я пробовал это, но это не сработало:

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

Что я ошибся?

И возможно ли управлять утверждениями «! =» В случае? Такие как:

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

Ваш case примера работает для меня, но обратите внимание, что вы сравниваете конкатенацию A и B , поэтому шаблон будет соответствовать также, если, скажем, A является xy и B пуст. (Я думаю, что двойные кавычки в середине являются избыточными.) В case только одного слова для сравнения с шаблонами, поэтому вы не можете сравнивать несколько переменных, кроме как путем конкатенации.

В стандартном test , или [ команда, оператор сравнения = . == работает в некоторых системах, но не во всех. Кроме того, комбинирование условий с использованием -a проблематично, по крайней мере, с такими условиями, как -n . (см. этот вопрос ). Лучше использовать, if [ "$A" = x ] && [ "$B" = y ] ; then ... if [ "$A" = x ] && [ "$B" = y ] ; then ...

Что касается инвертирования case , вам нужно создать шаблон, который соответствует всем, кроме целевой строки. extglob в Bash и другие позволяет сопоставлять что угодно, кроме:

 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 вместо оболочки, а не просто из-за простых сравнений, а потому, что они позволят вам делать больше, не вызывая внешние программы (например, grep , sed , cut , или jq ). Кроме того, первое правило оптимизации производительности: измерить разницу.

 # $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