Existe-t-il un bon moyen de vérifier si un tableau a un élément dans bash (mieux que de boucler)?
Sinon, existe-t-il un autre moyen de vérifier si un nombre ou une chaîne est égal à l'un des constantes prédéfinies?
Dans Bash 4, vous pouvez utiliser des tableaux associatifs:
# set up array of constants
declare -A array
for constant in foo bar baz
do
array[$constant]=1
done
# test for existence
test1="bar"
test2="xyzzy"
if [[ ${array[$test1]} ]]; then echo "Exists"; fi # Exists
if [[ ${array[$test2]} ]]; then echo "Exists"; fi # doesn't
Pour configurer initialement le tableau, vous pouvez également effectuer des affectations directes:
array[foo]=1
array[bar]=1
# etc.
ou de cette façon:
array=([foo]=1 [bar]=1 [baz]=1)
${array[$test1]}
est simple mais a un problème: cela ne fonctionnera pas si vous utilisezset -u
dans vos scripts (ce qui est recommandé), car vous obtiendriez une "variable non liée".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 solide pour l'écriture .Il est une vieille question, mais je pense que ce qui est la solution la plus simple n'a pas encore apparu:
test ${array[key]+_}
. Exemple:Les sorties:
Pour voir comment cela fonctionne, vérifiez cela .
la source
env
pour éviter les ambiguïtés dans les alias, progs et autres fonctions qui peuvent avoir adopté le nom "test". Comme ci-dessusenv test ${xs[a]+_} && echo "a is set"
. Vous pouvez également obtenir cette fonctionnalité en utilisant des crochets doubles, la même astuce que la vérification de null:[[ ! -z "${xs[b]+_}" ]] && echo "b is set"
[[ ${xs[b]+set} ]]
Il existe un moyen de tester si un élément d'un tableau associatif existe (non défini), c'est différent de vide:
Ensuite, utilisez-le:
la source
if ! some_check then return 1
=some_check
. Donc:isNotSet() { [[ ... ]] }
. Consultez ma solution ci-dessous, vous pouvez le faire en une simple vérification.Vous pouvez voir si une entrée est présente en redirigeant le contenu du tableau vers grep.
Vous pouvez également obtenir l'index d'une entrée avec grep -n, qui renvoie le numéro de ligne d'une correspondance (n'oubliez pas de soustraire 1 pour obtenir un index de base zéro). Ce sera assez rapide, sauf pour les très grands tableaux.
explication:
$( ... )
revient à utiliser des astuces pour capturer la sortie d'une commande dans une variableprintf
affiche mydata un élément par ligne@
lieu de*.
cela évite de diviser "bonjour le monde" en 2 lignes)grep
recherche la chaîne exacte:^
et fait$
correspondre le début et la fin de la lignegrep -n
retourne la ligne #, en forme de 4: bonjour le mondegrep -m 1
trouve la première correspondance uniquementcut
extrait uniquement le numéro de ligneVous pouvez bien sûr replier la soustraction dans la commande. Mais testez ensuite -1 pour manquer:
$(( ... ))
fait l'arithmétique entièrela source
Je ne pense pas que vous puissiez le faire correctement sans boucle, sauf si vous avez des données très limitées dans le tableau.
Voici une variante simple, cela dirait correctement qu'il
"Super User"
existe dans le tableau. Mais cela voudrait aussi dire que"uper Use"
c'est dans le tableau.Le problème est qu'il n'y a pas de moyen facile d'ajouter les ancres (auxquelles je peux penser) en plus de parcourir le tableau. À moins que vous ne puissiez les ajouter avant de les mettre dans le tableau ...
la source
grep "\b$FINDME\b"
). Peut probablement fonctionner avec des constantes non alphanumériques qui n'ont pas d'espaces, avec"(^| )$FINDME(\$| )"
(ou quelque chose comme ça ... Je n'ai jamais pu apprendre quelle saveur de grep regexp utilise.)la source
in_array
. Cheers${ARRAY[@]}
être utilisé.