Чи можуть каскадні висловлювання у випадку каскаду?


29

Я намагаюся зробити щось подібне:

case $level in
    3)
        echo "Level Three"

    2)
        echo "Level Two"

    1)
        echo "Level one"
        ;;
esac

де, якби $ рівень = 3, він виведе

Level Three
Level Two
Level One

тоді як якщо $ level = 1, він буде виводити тільки

Level One

Але коли я спробую це, я отримую помилку, syntax error near unexpected token ')'тому що не включив ;;.

Кожна інша мова, яку я знаю, дозволяє це, чи є спосіб це зробити в башті? Якесь ключове слово, яке означає "зараз продовжуй і роби наступний випадок так, ніби воно збігається"?


2
Якщо кожна відома вам мова дозволяє це, вам потрібно вивчити інші мови, крім C та його імітаторів. Прорив у випадках, коли висловлювання є історичною дизайнерською аварією в С, яка якось вижила на більш принципових мовах.
Жил "ТАК - перестань бути злим"

Відповіді:


42

Вам потрібно скористатися ;&замість того, ;;щоб отримати поведінку, що пропадає:

#! /bin/bash
foo() {
    case "$1" in
        3)
            echo "Level Three"
            ;&
        2)
            echo "Level Two"
            ;&
        1)
            echo "Level One"
            ;;
        a)
            echo "Level a"
            ;&
        b)
            echo "Level b"
            ;&
        c)
            echo "Level c"
            ;;
    esac
}
echo 3:
foo 3
echo 2:
foo 2
echo a:
foo a
3:
Level Three
Level Two
Level one
2:
Level Two
Level one
a:
Level a
Level b
Level c

Дивіться розділ « Умовні конструкції» документації на баш.

Іншим спеціальним маркером є ;;&:

змушує оболонку перевіряти шаблони в наступному пункті, якщо такі є, і виконувати будь-який пов'язаний список команд при успішному збігу.

;; завжди остаточний, подальші зразки не перевіряються.

#! /bin/bash

foo() {
    case "$1" in
        *3*)
            echo "Level Three"
            ;;&
        *2*)
            echo "Level Two"
            ;;&
        *1*)
            echo "Level One"
            ;;&
    esac
}

echo 12:
foo 12
echo 13:
foo 13
echo 23:
foo 23
12:
Level Two
Level One
13:
Level Three
Level One
23:
Level Three
Level Two

18
Примітка про переносимість: цей синтаксис не є POSIX. Воно походить від kshі доступний в ksh, bash(починаючи з 4.0, 2009) та zsh(з 3.1.2, 1997). ;;&є специфічним для bash.
Стефан Шазелас

4
Також зауважте, що zshеквівалент bash's ;;&є ;|(додано в 4.3.3, 2007).
Стефан Шазелас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.