if [ foo = bar -o foo = car -o foo = jar -o foo = foo ]
then
echo yes
fi
Um die Organisation zu verbessern, möchte ich versuchen, sie einer Liste zuzuordnen, z
if [ foo = {bar,car,jar,foo} ] ; then
Offensichtlich hat die Methode zur Erweiterung der geschweiften Klammer nicht funktioniert, sonst wäre ich nicht hier! Aber ich würde gerne wissen, ob so etwas überhaupt möglich ist.
select
ist (normalerweise) für die manuelle Eingabe gedacht , also haben Sie vielleicht darüber nachgedacht. Übrigens, wenn Sie keine Operation ausführen müssen, wenn keine Übereinstimmung vorliegt, können Sie die*)
Zeile vollständig entfernen . dann könnten Sie das Ganze in eine einzige Zeile setzen, ohne die Lesbarkeit wirklich zu beeinträchtigen.case $input in
Leitung, deshalb denkt OP, dass es nur für Eingaben ist.Es sieht aus wie ein Fehler in Ihrem Code, aber wir können ihn sehr klein umgestalten ...
Wenn Sie Ihren Ausdruck wirklich mit geschrieben hätten
[ foo = bar -o foo = car -o foo = jar -o foo = foo ]
, hätte er vereinfacht werden können zu:Dieser Test ist immer wahr, weil er
foo = foo
immer wahr ist, was wiederum darauf zurückzuführen ist, dass die Literalzeichenfolgefoo
immer dieselbe ist wie sie selbst.Obwohl Sie klargestellt haben, dass diese Syntax nicht in dem Code enthalten ist, den Sie wirklich verwendet haben, habe ich diesen einleitenden Abschnitt beibehalten, da dies ein häufiger Fehler ist, insbesondere bei Anfängern. Der Versuch, den Wert auf
foo
diese Weise zu überprüfen, funktioniert in keiner Bourne-Shell - um den Wert einer Variablen mit zu untersuchen[
, müssen Sie eine Parametererweiterung mit durchführen$
(siehe unten). Dieser spezielle Aspekt des Problems ist nicht Shell-spezifisch. Hier ist zum Beispiel ein Test in 7 Bourne-Muscheln .Korrigieren des Originalcodes
Vielleicht wollten Sie stattdessen den Wert der
foo
Variablen (dh ihren Inhalt und nicht ihren Namen) anhand dieser Zeichenfolgen überprüfen . In diesem Fall würde Ihr ursprünglicher Code wie folgt aussehen:Dies kann mit dem Kurzschlussbediener leicht verkürzt
&&
werden:Aber es ist immer noch länger und komplizierter und wiederholt sich, als Sie wahrscheinlich bevorzugen. Also weiter ...
Kürzere Formulare über Pattern Matching
Sie können den in der
[[
Einrichtung integrierten Operator für den Abgleich regulärer Ausdrücke verwenden:Während die Verwendung
case
wahrscheinlich der häufigste Weg ist, ist[[
mit=~
:case
(siehe unten)[[
, der ähnlich wie ein Testausdruck funktioniert.Vielleicht bevorzugen Sie das also. Es ist die Methode, die ich wahrscheinlich verwenden würde, um dies in Bash zu tun.
Wenn Sie so etwas tun wollten, aber mit
grep
statt[[
mit übereinstimmen=~
, ist dies ähnlich:Oder dieses:
Ein Einzeiler mit
case
Wie Serg sagt , kann unter Verwendung vereinfacht werden
case
stattif
und[
. Das ist der klassische und wahrscheinlich häufigste Weg.Die Methode in Sergs Antwort funktioniert einwandfrei, aber für den bestimmten Code, den Sie umgestalten, können wir etwas Einfacheres schreiben, indem wir nur ein Muster für verwenden
case
. Am Ende muss kein Allround-*)
Match stattfinden. Wenn die Zeichenfolge keinem der Muster entspricht, durchläuft die Steuerung einfach das case-Konstrukt und es werden keine Befehle ausgeführt, was Ihremif
Konstrukt mit no entsprichtelse
.Das macht es kurz und einfach genug, um leicht in eine einzelne Zeile zu passen - und lesbar zu sein (was genau das zu sein scheint, wonach Sie suchen). Diese Methode kann auch auf andere Bourne-Shells als Bash übertragen werden.
quelle
[[ $foo =~ ^(bar|car|jar|foo)$ ]] && echo yes
aber so wie ich es verstehe und wie Sie es formuliert haben, wäre es nicht für andere Muscheln tragbar? Glaubst du wirklich, dass es ein Fehler ist? Es kann einfach kein Merkmal der if-Aussage sein, die ich denke. Ich mag die Fallmethode, die Serg angesprochen hat, sehr. Wäre ich ein Idiot, wenn ich Ihre in die akzeptierte Antwort ändern würde? Ich bin sicher, wir können uns alle einig sein, dass Sie mit mehr Details und Methoden ein bisschen mehr darüber nachdenken, aber ich würde mich schrecklich schlecht fühlen, wenn ich ihn "nicht belohne". Serg, wenn du das liest, gib mir bitte deine 2 ¢foo
, haben jedochfoo = foo
die Literalzeichenfolgefoo
und nichtfoo
den Wert auf beiden Seiten von=
. • Sie haben Recht, dass[[
es nicht auf alle Bourne-Shells portierbar ist (dh es sollte nicht in einem#!/bin/sh
Skript verwendet werden), obwohl einige andere es gerneksh
haben. • Es ist zwar in Ordnung, eine Antwort zu akzeptieren und eine andere zu akzeptieren, aber ich glaube nicht, dass Sie dies in diesem Fall tun müssen. Sergs Antwort ist auch richtig und gut. Vielleicht möchten Sie auch abwarten, welche anderen Antworten veröffentlicht werden.[
Vergleiche mit unbeabsichtigt nicht expandierten Variablen ist eigentlich eine etwas gemeinsam Shell - Scripting Fehler (obwohl, wie Sie geklärt haben, waren Sie eigentlich nicht , dass Fehler im Code , dass Sie wurden ausgeführt wird ). Aber ich habe es umformuliert, um dies widerzuspiegeln.Noch kürzer:
Auf diese Weise
$foo
wird abgeglichen gegen einen regulären Ausdruck entweder beginnend mitb
,c
oderj
gefolgt vonar
oder genau passendfoo
.Dies verwendet den
&&
Operator als Kurzschluss, umecho yes
nur ausgeführt zu werden, wenn der[[ $foo =~ ^([bcj]ar|foo)$ ]]
Ausdruck als wahr ausgewertet wird.Wenn dies zu kompakt ist, um problemlos gelesen zu werden, können Sie immer noch das vollständige if-Konstrukt verwenden, das genau das Gleiche tut, aber besser lesbar ist:
quelle