Можно ли использовать фигурные скобки в случае выбора в bash? - PullRequest
0 голосов
/ 16 июня 2019

Я хочу выполнить некоторые действия для совпавших строк в переключателе регистра.И поскольку строки длинные, я хотел использовать фигурные скобки bash.Но это не работает.

Этот код без фигурных скобок работает как ожидалось:

for i in longstr_one longstr_two; do
    case $i in
    longstr_one| longstr_five)
        echo matched $i
        ;;
        *)
        echo no matches of $i
        ;;
    esac
done

И я получил ожидаемый результат:

matched longstr_one
no matches of longstr_two

Но следующий код сфигурные скобки не:

for i in longstr_one longstr_two; do
    case $i in
    longstr_{one|,five})
        echo matched $i
        ;;
        *)
        echo no matches of $i
        ;;
    esac
done   

И я получил неправильный результат:

no matches of longstr_one
no matches of longstr_two

Почему это не работает?Можно ли использовать фигурные скобки в селекторе case в bash?

Ответы [ 3 ]

4 голосов
/ 16 июня 2019

Из Руководство по bash :

case
Синтаксис команды case:

case word in
      [ [(] pattern [| pattern]…) command-list ;;]…
esac

...
... Каждый шаблон подвергается расширению тильды, расширению параметров, подстановке команд и арифметическому расширению.
...

Это означает, что расширение скобки не выполняется для case ' pattern , поэтому здесь его невозможно использовать.

3 голосов
/ 16 июня 2019

Поскольку расширение фигурных скобок не выполняется в шаблонах case, вместо этого вы можете использовать расширенный синтаксис glob для bash:

shopt -s extglob

for i in longstr_one longstr_two; do
    case $i in
    longstr_@(one|five) )
        echo "matched $i"
        ;;
        *)
        echo "no matches of $i"
        ;;
    esac
done

Синтаксис @(this|that|theother|...) соответствует любому из подшаблонов.

1 голос
/ 16 июня 2019

Вместо сопоставления по всему значению i, просто сопоставьте оставшуюся часть после удаления общего префикса.

for i in longstr_one longstr_two; do
    case ${i#longstr_} in
    one|five)
        echo matched $i
        ;;
        *)
        echo no matches of $i
        ;;
    esac
done

Этот подход не зависит от каких-либо нестандартных расширений, таких как extglob.

...