Ich versuche, ein Skript in Bash zu schreiben, das die Gültigkeit einer Benutzereingabe überprüft.
Ich möchte die Eingabe (z. B. Variable x
) mit einer Liste gültiger Werte abgleichen.
Was ich mir im Moment ausgedacht habe, ist:
for item in $list
do
if [ "$x" == "$item" ]; then
echo "In the list"
exit
fi
done
Meine Frage ist, ob es einen einfacheren Weg gibt, so
etwas wie einen list.contains(x)
für die meisten Programmiersprachen.
Ergänzung:
Sagen Sie Liste ist:
list="11 22 33"
Mein Code gibt die Nachricht nur für diese Werte wieder, da list
sie als Array und nicht als Zeichenfolge behandelt werden. Alle Zeichenfolgenmanipulationen werden überprüft, 1
solange ich möchte, dass sie fehlschlagen.
[[ $list =~ (^| )$x($| ) ]] && echo 'yes' || echo 'no'
x=.
contains () { [[ "$1" =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; }
.[[ " $list " =~ " $x " ]] && echo 'yes' || echo 'no'
. Es ist richtig, wenn Leerzeichen das Trennzeichen sind und$x
kein Leerzeichen enthaltenisIn()
damit Sie das Element zuerst in Parameter schreiben können. Sie können auchecho
etwas anstattexit
wie[[ $2 =~ (^|[[:space:]])$1($|[[:space:]]) ]] && echo 1 || echo 0
result=$(isIn "-t" "-o -t 45") && echo $result
Matvey hat recht, aber Sie sollten $ x zitieren und jede Art von "Leerzeichen" (z. B. neue Zeile) mit berücksichtigen
also, dh
dann ende
oder
Beachten Sie, dass Sie
""
bei Variablen Folgendes verwenden müssen :quelle
$item
spezielle Zeichen enthält, wie.
(aber die$list
Variable muss wahrscheinlich im Test in Anführungszeichen gesetzt werden). Und die Funktion kann noch einfacher definiert werden :contains () { [[ "$1" =~ (^|[[:space:]])"$2"($|[[:space:]]) ]]; }
.list="aa bb xx cc ff"
undx="aa bb"
$list =~ (^|[[:space:]])"$item"($|[[:space:]])
. Oder wenn Sie Zeit haben, würde ich mich über Ihre Erklärung für diesen Ausdruck freuen. Hinweis: Ich denke, es ist ein regulärer Ausdruck (beginnt mit ^ usw.), aber ich weiß nicht, was = ~ bedeutet. Also ich würde eine allgemeine Erklärung lieben: PIMHO einfachste Lösung ist es, die ursprüngliche Zeichenfolge mit einem Leerzeichen voranzustellen und anzuhängen und mit einem regulären Ausdruck mit zu vergleichen
[[ ]]
Dies ist bei Werten mit Werten, die die Nadel als Teilzeichenfolge enthalten, z
foo barbaz
. B. mit einem Heuhaufen, nicht falsch positiv .(Das Konzept wird schamlos von JQuery's
hasClass()
-Method gestohlen )quelle
haystack="foo:bar"
und[[ ":$haystack:" = *:$needle:* ]]
wie wäre es mit
Sie können entweder die Ausgabe oder die
$?
obige Zeile überprüfen , um die Entscheidung zu treffen.grep -w
prüft ganze Wortmuster.quelle
Sie können (* Platzhalter) auch außerhalb einer case-Anweisung verwenden, wenn Sie doppelte Klammern verwenden:
quelle
*My*
) auf der rechten Seite des Tests befinden müssen.Wenn Ihre Werteliste im Skript fest codiert werden soll, ist das Testen ziemlich einfach
case
. Hier ist ein kurzes Beispiel, das Sie an Ihre Anforderungen anpassen können:Wenn die Liste zur Laufzeit eine Array-Variable ist, passt wahrscheinlich eine der anderen Antworten besser.
quelle
Wenn die Liste im Skript festgelegt ist, gefällt mir Folgendes am besten:
Dann verwenden Sie
validate "$x"
, um zu testen, ob$x
zulässig ist.Wenn Sie einen Einzeiler möchten und sich nicht für Leerzeichen in Elementnamen interessieren, können Sie dies verwenden (Hinweis
-w
anstelle von-x
):Anmerkungen:
sh
konform.validate
ist nicht Substrings akzeptieren (die entfernen-x
Option grep , wenn Sie das wollen).validate
interpretiert sein Argument als feste Zeichenfolge, nicht als regulären Ausdruck (entfernen Sie die-F
Option zu grep, wenn Sie dies möchten).Beispielcode zur Ausübung der Funktion:
quelle
Ziehen Sie in Betracht, die Schlüssel von assoziativen Arrays auszunutzen . Ich würde annehmen, dass dies sowohl Regex / Pattern Matching als auch Looping übertrifft, obwohl ich es nicht profiliert habe.
Ausgabe:
quelle
echo -n
durch kreative Verwendung von Parametern vereinfachen (und sich nicht darauf verlassen ) :do is="${list[$value]+is }"; echo "$value ${is:-is *not* }a member of ( ${!list[*]} )"; done
.Ich finde es einfacher, das
echo $LIST | xargs -n1 echo | grep $VALUE
unten abgebildete Formular zu verwenden :Dies funktioniert für eine durch Leerzeichen getrennte Liste. Sie können sie jedoch wie
:
folgt an ein anderes Trennzeichen (wie z. B. ) anpassen :Beachten Sie, dass die
"
erforderlich sind, damit der Test funktioniert.quelle
LIST="SOMEITEM1 ITEM2"
, dass true zurückgegeben wird, obwohlITEM1
es nicht enthalten istIch dachte, ich würde meine Lösung zur Liste hinzufügen.
quelle
Beispiele
in_list
quelle
Angenommen, die TARGET-Variable kann nur "Binomial" oder "Regression" sein, dann würde Folgendes reichen:
Sie können der Liste weitere Zeichenfolgen hinzufügen, indem Sie sie durch ein | trennen (Rohr-) Charakter.
Der Vorteil der Verwendung von egrep besteht darin, dass Sie leicht die Groß- und Kleinschreibung (-i) hinzufügen oder komplexere Szenarien mit einem regulären Ausdruck überprüfen können.
quelle
Dies ist fast Ihr ursprünglicher Vorschlag, aber fast ein 1-Liner. Nicht so kompliziert wie andere gültige Antworten und nicht so abhängig von den Bash-Versionen (kann mit alten Bashes funktionieren).
Ich denke, mein Vorschlag kann sowohl in der Länge als auch im Stil noch verbessert werden.
quelle
Wenn es nicht zu lang ist; Sie können sie einfach zwischen Gleichheit entlang eines logischen ODER-Vergleichs wie folgt anordnen.
Ich hatte genau dieses Problem und obwohl das oben Gesagte hässlich ist, ist es offensichtlicher, was vor sich geht als die anderen verallgemeinerten Lösungen.
quelle