2010-12-29 9 views
43

Strona man podaje, że w instrukcjach case używane jest "dopasowanie wzorca rozszerzenia nazwy pliku".
zazwyczaj chcą mieć krótkie nazwy dla niektórych parametrów, więc idę:Jak używać wzorców w instrukcji case w skryptach bash?

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

logTimeSpentIn "$TASK" 

Próbowałem wzory jak req* lub me{e,}t który rozumiem rozwinie prawidłowo dopasować te wartości w kontekście rozszerzania nazw, ale nie działa.

Odpowiedz

24

Nie sądzę, aby można było używać aparatów ortodontycznych.

Zgodnie z instrukcją Bash dotyczącą przypadku w Conditional Constructs.

Każdy wzór ulega tylda ekspansji, ekspansji parametrach polecenia zastępowanie arytmetycznym ekspansji.

Niestety nie ma informacji o Brace Expansion.

Więc trzeba by zrobić coś takiego:

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

+1 dla przykładu "met * | meet *". – JohnJ

92

nawiasów nie działa, ale *, ? i [] zrobić. Jeśli ustawisz shopt -s extglob następnie można również użyć extended pattern matching:

  • ?() - zero lub jeden wystąpień wzorca
  • *() - zero lub więcej wystąpień wzorca
  • +() - jeden lub więcej wystąpień wzorca
  • @() - jedno wystąpienie wzorca
  • !() - dowolne z wyjątkiem wzorca

Oto przykład:

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 
+0

Link do dokumentacji na temat: https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching – phyatt

+0

@phyatt: Thanks. Dodałem link do mojej odpowiedzi. –

0

if i grep -E więcej rozwiązanie przenośne

Dla przenośności, polecam, po prostu użyć if oświadczenia i grep -E który obsługuje extended regular expressions, na przykład:

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 wydaje się podążać POSIX domyślnie bez shopt jak wspomniano przez https://stackoverflow.com/a/4555979/895245

Oto cytat: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_01 sekcja "Case Warunkowe Construct":

Konstrukcja warunkowa powinna zawierać listę złożoną odpowiadającą pierwszemu jeden z kilku wzorców (patrz Pattern Matching Notation) [...] Wiele wzorów z tą samą złożoną listą zostanie rozdzielonych przez "|" symbol. [...]

format dla przypadku konstrukcji jest następujący:

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

i http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_13 sekcja wymienia tylko ?, * i [] "2,13 Wzór Dopasowane notacji.".

Powiązane problemy