2012-11-06 14 views
18

Próbuję napisać skrypt Bash, który używa zmiennej jako wzorca w instrukcji case. Jednak po prostu nie mogę go uruchomić.Używanie zmiennej jako wzorca sprawy w Bash

case:

case "$1" in 
    $test) 
     echo "matched" 
     ;; 
    *) 
     echo "didn't match" 
     ;; 
esac 

Próbowałem to z przypisywania $test jak aaa|bbb|ccc, (aaa|bbb|ccc), [aaa,bbb,ccc] i kilka innych kombinacji. Próbowałem również tych jako wzór w przypadku: @($test), @($(echo $test)), $($test). Nie ma też sukcesu.

EDIT

Dla jasności chciałbym zmiennej do reprezentowania wielu wzorców tak:

case "$1" in 
    aaa|bbb|ccc) 
     echo "matched" 
     ;; 
    *) 
     echo "didn't match" 
     ;; 
esac 

Odpowiedz

17

Można użyć opcji extglob:

#! /bin/bash 

shopt -s extglob   # enables pattern lists like +(...|...) 
test='+(aaa|bbb|ccc)' 

for x in aaa bbb ccc ddd ; do 
    echo -n "$x " 
    case "$x" in 
     $test) echo Matches. 
     ;; 
     *) echo Does not match. 
    esac 
done 
+2

+1 za przypomnienie mi użycia 'extgloba'. Nawiasem mówiąc, 'test = '@ (aaa | bbb | ccc)' 'również działa i jest prawdopodobnie lepszą opcją w tym przypadku. – anubhava

+0

To jest niesamowite! Dzięki! @anubhava Dlaczego twoja sugestia byłaby lepsza (@ zamiast +)? – siebz0r

+1

@anubhava Nieważne, znalazłem [tutaj] (https://www.gnu.org/software/bash/manual/html_node/Pattern-Matching.html#Pattern-Matching). @ dopasowuje jedno wystąpienie, + dopasowuje wiele. – siebz0r

3

(Updated): tutaj coś nieco inna, ale mam nadzieję, że to działa w zależności od potrzeb:

#!/bin/bash 

pattern1="aaa bbb ccc" 
pattern2="hello world" 
test=$(echo -e "$pattern1\n$pattern2" | grep -e $1) 

case "$test" in 
    "$pattern1") 
     echo "matched - pattern1" 
     ;; 
    "$pattern2") 
     echo "matched - pattern2" 
     ;; 
    *) 
     echo "didn't match" 
     ;; 
esac 

Wykorzystuje to grep, aby dopasować wzorzec dla ciebie, ale nadal pozwala określić wiele zestawów wzorów, które będą używane w strukturze instrukcji case.

Na przykład:

  • Jeśli któryś aaa, bbb lub ccc jest pierwszy argument do skryptu, to wyjście będzie matched - pattern1.
  • Jeśli pierwszym argumentem jest hello lub world, wyświetli się matched - pattern2.
  • W przeciwnym razie wyświetli się didn't match.
+2

to może działać, jeśli $ 1 aaa, bbb i nie dla ccc. – Guru

+0

@Guru ma rację. To pasuje tylko do pierwszego, ponieważ 'test' staje się' aaa'. – siebz0r

+0

@ siebz0r zaktualizowana odpowiedź - sprawdź, czy to działa. –

1

używając eval działa również:

eval 'case "$1" in 

    '$test') 
     echo "matched" 
     ;; 
    *) 
     echo "did not match" 
     ;; 
esac' 
Powiązane problemy