Gibt es eine gute Möglichkeit zu überprüfen, ob ein Array ein Element in bash enthält (besser als eine Schleife durchzuführen)?
Gibt es alternativ eine andere Möglichkeit, um zu überprüfen, ob eine Zahl oder eine Zeichenfolge einer Reihe vordefinierter Konstanten entspricht?
${array[$test1]}
ist einfach, hat aber ein Problem: Es funktioniert nicht, wenn Sieset -u
in Ihren Skripten verwenden (was empfohlen wird), da Sie "ungebundene Variable" erhalten würden.set -u
: davidpashley.com/articles/writing-robust-shell-scripts.html , blog.hashbang0.com/2010/05/18/robust-bash-scripts-part-one , openews.net/2012/bash- script-to-write-robust .Es ist eine alte Frage, aber ich denke , was die einfachste Lösung schien noch nicht ist:
test ${array[key]+_}
. Beispiel:Ausgänge:
Um zu sehen, wie dies funktioniert, überprüfen Sie dies .
quelle
env
, um Unklarheiten in Aliasen, Progs und anderen Funktionen zu vermeiden, die möglicherweise den Namen "Test" angenommen haben. Wie obenenv test ${xs[a]+_} && echo "a is set"
. Sie können diese Funktion auch mit doppelten Klammern erhalten, wobei derselbe Trick dann auf null prüft:[[ ! -z "${xs[b]+_}" ]] && echo "b is set"
[[ ${xs[b]+set} ]]
Es gibt eine Möglichkeit zu testen, ob ein Element eines assoziativen Arrays existiert (nicht gesetzt). Dies unterscheidet sich von leer:
Dann benutze es:
quelle
if ! some_check then return 1
=some_check
. Also:isNotSet() { [[ ... ]] }
. Überprüfen Sie meine Lösung unten, Sie können es in einem einfachen Check tun.Sie können feststellen, ob ein Eintrag vorhanden ist, indem Sie den Inhalt des Arrays an grep weiterleiten.
Sie können auch den Index eines Eintrags mit grep -n abrufen, der die Zeilennummer einer Übereinstimmung zurückgibt (denken Sie daran, 1 zu subtrahieren, um einen auf Null basierenden Index zu erhalten). Dies ist mit Ausnahme sehr großer Arrays relativ schnell.
Erläuterung:
$( ... )
entspricht der Verwendung von Backticks zum Erfassen der Ausgabe eines Befehls in eine Variableprintf
gibt mydata ein Element pro Zeile aus@
anstatt*.
dies vermeidet Splitting „Hallo Welt“ in 2 Zeilen)grep
Sucht nach genauem String:^
und$
stimmt mit Zeilenanfang und Zeilenende übereingrep -n
Gibt Zeile # in Form von 4 zurück: Hallo Weltgrep -m 1
findet nur die erste Übereinstimmungcut
extrahiert nur die ZeilennummerSie können die Subtraktion natürlich in den Befehl einklappen. Aber dann teste auf -1, ob etwas fehlt:
$(( ... ))
führt eine Ganzzahl-Arithmetik durchquelle
Ich denke nicht, dass Sie es ohne Schleife richtig machen können, es sei denn, Sie haben sehr begrenzte Daten im Array.
Hier ist eine einfache Variante, dies würde richtig sagen, dass
"Super User"
es in dem Array existiert. Aber es würde auch sagen, dass"uper Use"
das in der Reihe ist.Das Problem ist, dass es keine einfache Möglichkeit gibt, die Anker (die ich mir vorstellen kann) hinzuzufügen, außer das Array zu durchlaufen. Es sei denn, Sie können sie hinzufügen, bevor Sie sie in das Array einfügen ...
quelle
grep "\b$FINDME\b"
)."(^| )$FINDME(\$| )"
Könnte wahrscheinlich mit nicht-alphanumerischen Konstanten arbeiten, die keine Leerzeichen haben, mit (oder so ähnlichem ... Ich habe nie erfahren können, welche Variante von Regexp grep verwendet.)quelle
in_array
. Cheers${ARRAY[@]}
verwendet werden.