Réponses:
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 utilisez set -u
dans vos scripts (ce qui est recommandé), car vous obtiendriez une "variable non liée".
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:
declare -A xs=([a]=1 [b]="")
test ${xs[a]+_} && echo "a is set"
test ${xs[b]+_} && echo "b is set"
test ${xs[c]+_} && echo "c is set"
Les sorties:
a is set
b is set
Pour voir comment cela fonctionne, vérifiez cela .
env
pour éviter les ambiguïtés dans les alias, progs et autres fonctions qui peuvent avoir adopté le nom "test". Comme ci-dessus env 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:
isNotSet() {
if [[ ! ${!1} && ${!1-_} ]]
then
return 1
fi
}
Ensuite, utilisez-le:
declare -A assoc
KEY="key"
isNotSet assoc[${KEY}]
if [ $? -ne 0 ]
then
echo "${KEY} is not set."
fi
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.
printf "%s\n" "${mydata[@]}" | grep "^${val}$"
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.
# given the following data
mydata=(a b c "hello world")
for val in a c hello "hello world"
do
# get line # of 1st matching entry
ix=$( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 )
if [[ -z $ix ]]
then
echo $val missing
else
# subtract 1. Bash arrays are zero-based, but grep -n returns 1 for 1st line, not 0
echo $val found at $(( ix-1 ))
fi
done
a found at 0
c found at 2
hello missing
hello world found at 3
explication:
$( ... )
revient à utiliser des astuces pour capturer la sortie d'une commande dans une variable printf
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 monde grep -m 1
trouve la première correspondance uniquementcut
extrait uniquement le numéro de ligne Vous pouvez bien sûr replier la soustraction dans la commande. Mais testez ensuite -1 pour manquer:
ix=$(( $( printf "%s\n" "${mydata[@]}" | grep -n -m 1 "^${val}$" | cut -d ":" -f1 ) - 1 ))
if [[ $ix == -1 ]]; then echo missing; else ... fi
$(( ... ))
fait l'arithmétique entièreJe 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.
MyArray=('Super User' 'Stack Overflow' 'Server Fault' 'Jeff' );
FINDME="Super User"
FOUND=`echo ${MyArray[*]} | grep "$FINDME"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
#
# If you where to add anchors < and > to the data it could work
# This would find "Super User" but not "uper Use"
#
MyArray2=('<Super User>' '<Stack Overflow>' '<Server Fault>' '<Jeff>' );
FOUND=`echo ${MyArray2[*]} | grep "<$FINDME>"`
if [ "${FOUND}" != "" ]; then
echo Array contains: $FINDME
else
echo $FINDME not found
fi
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 ...
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.)
#!/bin/bash
function in_array {
ARRAY=$2
for e in ${ARRAY[*]}
do
if [[ "$e" == "$1" ]]
then
return 0
fi
done
return 1
}
my_array=(Drupal Wordpress Joomla)
if in_array "Drupal" "${my_array[*]}"
then
echo "Found"
else
echo "Not found"
fi
in_array
. Cheers
${ARRAY[@]}
être utilisé.