Próbuję napisać skrypt w bash, który sprawdza poprawność danych wejściowych użytkownika.
Chcę dopasować dane wejściowe (powiedzmy zmienną x
) do listy prawidłowych wartości.
w tej chwili wymyśliłem:
for item in $list
do
if [ "$x" == "$item" ]; then
echo "In the list"
exit
fi
done
Moje pytanie brzmi, czy istnieje prostszy sposób na zrobienie tego,
coś w rodzaju a list.contains(x)
dla większości języków programowania.
Dodatek:
Lista wypowiedzi to:
list="11 22 33"
mój kod powtórzy wiadomość tylko dla tych wartości, ponieważ list
jest traktowany jako tablica, a nie jako ciąg, wszystkie operacje na ciągach zostaną sprawdzone, 1
podczas gdy chciałbym, aby zakończyło się niepowodzeniem.
[[ $list =~ (^| )$x($| ) ]] && echo 'yes' || echo 'no'
x=.
contains () { [[ "$1" =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; }
.[[ " $list " =~ " $x " ]] && echo 'yes' || echo 'no'
. jest poprawne zakładając, że spacja jest separatorem i$x
nie zawiera spacjiisIn()
aby można było najpierw zapisać element w parametrach. Możesz teżecho
coś zamiast używać wexit
ten sposób:[[ $2 =~ (^|[[:space:]])$1($|[[:space:]]) ]] && echo 1 || echo 0
Więc możesz użyć funkcji w ten sposób:result=$(isIn "-t" "-o -t 45") && echo $result
Matvey ma rację, ale powinieneś zacytować $ x i rozważyć wszelkiego rodzaju "spacje" (np. Nowy wiersz) z
więc tj
wtedy koniec
lub
Zauważ, że musisz użyć
""
w przypadku zmiennych:źródło
$item
zawiera specjalne znaki, takie jak.
(ale$list
zmienna prawdopodobnie wymaga cytowania w teście). A funkcja może być zdefiniowana jeszcze prostsze:contains () { [[ "$1" =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; }
.list="aa bb xx cc ff"
ix="aa bb"
$list =~ (^|[[:space:]])"$item"($|[[:space:]])
. Lub, jeśli masz czas, z przyjemnością usłyszę wyjaśnienie tego wyrażenia. Uwaga: wydaje mi się, że jest to wyrażenie regularne (zaczyna się od ^ itd.), Ale nie wiem, co oznacza = ~. Chciałbym więc uzyskać ogólne wyjaśnienie: PNajłatwiejszym rozwiązaniem IMHO jest wstawienie i dołączenie oryginalnego ciągu spacją i sprawdzenie wyrażenia regularnego za pomocą
[[ ]]
nie będzie to fałszywie dodatnie w przypadku wartości zawierających igłę jako podciąg, np. ze stogiem siana
foo barbaz
.(Koncepcja została bezwstydnie skradziona z JQuery's
hasClass()
metody JQuery'ego)źródło
haystack="foo:bar"
i[[ ":$haystack:" = *:$needle:* ]]
Co powiesz na
$?
aby podjąć decyzję, możesz sprawdzić dane wyjściowe lub powyższą linię.grep -w
sprawdza całe wzorce słów.źródło
Możesz również użyć (* symboli wieloznacznych) poza instrukcją case, jeśli używasz podwójnych nawiasów:
źródło
*My*
) muszą znajdować się po prawej stronie testu.Jeśli lista wartości ma być zakodowana na stałe w skrypcie, jej przetestowanie przy użyciu jest dość proste
case
. Oto krótki przykład, który możesz dostosować do swoich wymagań:Jeśli lista jest zmienną tablicową w czasie wykonywania, prawdopodobnie lepiej pasuje jedna z pozostałych odpowiedzi.
źródło
Jeśli lista jest naprawiona w skrypcie, najbardziej lubię następujące:
Następnie użyj,
validate "$x"
aby sprawdzić, czy$x
jest dozwolone.Jeśli chcesz mieć jedną linijkę i nie obchodzą Cię białe znaki w nazwach elementów, możesz użyć tego (uwaga
-w
zamiast-x
):Uwagi:
sh
zgodne z POSIX .validate
ma nie przyjąć podciągi (usunąć-x
opcję grep jeśli chcesz to).validate
interpretuje jej argument jako ustalony ciąg znaków, a nie wyrażenie regularne (usuń-F
opcję grep, jeśli chcesz).Przykładowy kod do wykonania funkcji:
źródło
Rozważ wykorzystanie kluczy tablic asocjacyjnych . Zakładam, że to przewyższa zarówno dopasowywanie wyrażeń regularnych / wzorców, jak i zapętlanie, chociaż nie sprofilowałem tego.
Wynik:
źródło
echo -n
) z twórczego wykorzystania parametrów:do is="${list[$value]+is }"; echo "$value ${is:-is *not* }a member of ( ${!list[*]} )"; done
.Uważam, że łatwiej jest korzystać z formularza,
echo $LIST | xargs -n1 echo | grep $VALUE
jak pokazano poniżej:Działa to w przypadku listy oddzielonej spacjami, ale możesz dostosować ją do dowolnego innego separatora (np.
:
), Wykonując następujące czynności:Zwróć uwagę, że
"
są wymagane, aby test zadziałał.źródło
LIST="SOMEITEM1 ITEM2"
powrót prawdy, mimo żeITEM1
jej w niej nie maPomyślałem, że dodam moje rozwiązanie do listy.
źródło
Przykłady
na liście
źródło
Zakładając, że zmienna TARGET może być tylko „dwumianowa” lub „regresja”, to wystarczyłoby:
Możesz dodać więcej ciągów do listy, oddzielając je znakiem | (kreska).
Zaletą używania egrep jest to, że można łatwo dodać niewrażliwość na wielkość liter (-i) lub sprawdzić bardziej złożone scenariusze za pomocą wyrażenia regularnego.
źródło
To jest prawie twoja oryginalna propozycja, ale prawie 1-liniowa. Nie jest to tak skomplikowane, jak inne prawidłowe odpowiedzi, i nie tak w zależności od wersji basha (może działać ze starymi bashesami).
Myślę, że moją propozycję można jeszcze poprawić, zarówno pod względem długości, jak i stylu.
źródło
Jeśli to nie jest zbyt długie; możesz po prostu umieścić je między równościami wzdłuż logicznego porównania LUB, w ten sposób.
Miałem dokładnie ten problem i chociaż powyższe jest brzydkie, bardziej oczywiste jest, co się dzieje, niż inne uogólnione rozwiązania.
źródło