Как использовать шаблоны в инструкции case в сценариях bash?

На странице man указано, что операторы case используют "соответствие шаблону расширения имени файла".
Я обычно хочу иметь короткие имена для некоторых параметров, поэтому я иду:

case $1 in
    req|reqs|requirements) TASK="Functional Requirements";;
    met|meet|meetings) TASK="Meetings with the client";;
esac

logTimeSpentIn "$TASK"

Я пробовал такие шаблоны, как req* или me{e,}t, которые, как я понимаю, будут правильно расширяться, чтобы соответствовать этим значениям в контексте расширения имени файла, но он не работает.

42
задан 29 дек. '11 в 16:57
источник поделиться
3 ответов

Расширение скобки не работает, но *, ? и [] делают. Если вы установите shopt -s extglob, вы также можете использовать расширенное сопоставление образцов:

  • ?() - нуль или одно вхождение шаблона
  • *() - ноль или более вхождений шаблона
  • +() - одно или несколько вхождений шаблона
  • @() - одно появление шаблона
  • !() - ничего, кроме шаблона

Вот пример:

case $1 in
    a*             ) foo;;    # matches anything starting with "a"
    b?             ) bar;;    # matches any two-character string starting with "b"
    c[de]          ) baz;;    # matches "cd" or "ce"
    me?(e)t        ) qux;;    # matches "met" or "meet"
    @(a|e|i|o|u)   ) fuzz;;   # matches one vowel
    m+(iss)?(ippi) ) fizz;;   # matches "miss" or "mississippi" or others
esac
86
ответ дан 29 дек. '11 в 19:48
источник

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

Согласно руководству Bash о случае в условных конструкциях.

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

Ничего о Brace Expansion, к сожалению.

Итак, вам нужно сделать что-то вроде этого:

case $1 in
    req*)
        ...
        ;;
    met*|meet*)
        ...
        ;;
    *)
        # You should have a default one too.
esac
24
ответ дан 29 дек. '11 в 17:25
источник

if и grep -E более портативное решение

Для переносимости я рекомендую вам просто использовать операторы if и grep -E, которые поддерживают расширенные регулярные выражения, например:

arg='abc'
if echo "$arg" | grep -Eq 'a.c|d.*'; then
  echo 'first'
elif echo "$arg" | grep -Eq 'a{2,3}'; then
  echo 'second'
fi

POSIX 7

Bash, по-видимому, следует за POSIX по умолчанию без shopt, как указано qaru.site/questions/126416/...

Вот цитата: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01 раздел "Case Conditional Construct":

Случай условной конструкции должен выполнять составной список, соответствующий первому из нескольких шаблонов (см. Обозначение соответствия шаблону) [...] Несколько шаблонов с одним и тем же составным списком должны быть разделены символом '|' символ. [...]

Формат конструкции case выглядит следующим образом:

case word in
     [(] pattern1 ) compound-list ;;
     [[(] pattern[ | pattern] ... ) compound-list ;;] ...
     [[(] pattern[ | pattern] ... ) compound-list]
  esac

а затем http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13 раздел "2.13. Обозначение соответствия шаблону" означает только ?, * и [].

0
ответ дан 01 июля '17 в 11:59
источник

Другие вопросы по меткам или Задайте вопрос