Як використовувати шаблони у виписці справи?


81

На 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які, як я розумію, правильно розширюватимуться, щоб відповідати цим значенням у контексті розширення імені файлу, але це не працює.

Відповіді:


158

Фігурні дужки не працює, але *, ?і []зробити. Якщо ви встановите, shopt -s extglobви також можете використовувати розширене узгодження шаблонів :

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

Ось приклад:

shopt -s extglob
for arg in apple be cd meet o mississippi
do
    # call functions based on arguments
    case "$arg" 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
        *              ) bazinga;; # catchall, matches anything not matched above
    esac
done

2
Посилання на документацію щодо них: gnu.org/software/bash/manual/html_node/…
phyatt

@phyatt: Дякую. Я додав посилання до своєї відповіді.
Денніс Вільямсон

Ця відповідь мені допомогла, оскільки я вклав свій зразок у подвійні лапки ("a *"), і це не
спрацювало

44

Я не думаю, що ви можете користуватися брекетами.

Згідно з посібником Баша про справу в умовних конструкціях .

Кожен шаблон зазнає розширення тильди, розширення параметрів, підстановки команд та арифметичного розширення.

Нічого про розширення фігурних дужок на жаль, .

Отже, вам доведеться зробити щось подібне:

case $1 in
    req*)
        ...
        ;;
    met*|meet*)
        ...
        ;;
    *)
        # You should have a default one too.
esac

7

if і grep -Eq

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

де:

  • -q запобігає grep виробленню, він просто створює статус виходу
  • -E дозволяє розширені регулярні вирази

Мені це подобається, тому що:

Один мінус полягає в тому, що це, швидше за все, повільніше, ніж caseз тих пір, як викликає зовнішню grepпрограму, але я, як правило, вважаю продуктивність останньою, коли використовую Bash.

case є POSIX 7

Здається, Bash дотримується POSIX за замовчуванням, shoptяк не згадується на https://stackoverflow.com/a/4555979/895245

Ось цитата: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01 розділ "Умовна побудова справи":

У випадку умовної конструкції слід виконати складний список, що відповідає першому з кількох шаблонів (див. Позначення відповідності шаблонів) [...] Кілька шаблонів з одним і тим же складеним списком повинні бути обмежені знаком "|" символ. [...]

Формат конструкції випадку такий:

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. Позначення відповідності шаблону" лише згадує ?, *і [].

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.