L'index d'une valeur dans un tableau Bash
J'ai quelque chose dans bash
comme
myArray=('red' 'orange' 'green')
Et je voudrais faire quelque chose comme
echo ${myArray['green']}
Qui dans ce cas produirait 2
. Est-ce réalisable?
9 réponses
Cela va le faire:
#!/bin/bash
my_array=(red orange green)
value='green'
for i in "${!my_array[@]}"; do
if [[ "${my_array[$i]}" = "${value}" ]]; then
echo "${i}";
fi
done
Évidemment, si vous transformez cela en une fonction (par exemple get_index ()) - vous pouvez le rendre Générique
, Vous devez déclarer votre tableau avant de l'utiliser avec
declare -A myArray
myArray=([red]=1 [orange]=2 [green]=3)
echo ${myArray['orange']}
Non. Vous ne pouvez indexer qu'un tableau simple avec un entier dans bash
. Les tableaux associatifs (introduits dans bash
4) peuvent être indexés par des chaînes. Ils ne prévoient cependant pas le type de recherche inversée que vous demandez, sans un tableau associatif spécialement construit.
$ declare -A myArray
$ myArray=([red]=0 [orange]=1 [green]=2)
$ echo ${myArray[green]}
2
Il y a aussi une façon délicate:
echo ${myArray[@]/green//} | cut -d/ -f1 | wc -w | tr -d ' '
Et vous obtenez 2 Voici les références
C'est juste une autre façon d'initialiser un tableau associatif comme chepner l'a montré.
N'oubliez pas que vous devez explicitement declare
ou taper un tableau associatif avec l'attribut -A
.
i=0; declare -A myArray=( [red]=$((i++)) [orange]=$((i++)) [green]=$((i++)) )
echo ${myArray[green]}
2
Cela supprime le besoin de valeurs de code dur et rend peu probable que vous finissiez avec des doublons.
Si vous avez beaucoup de valeurs à ajouter, il peut aider à les mettre sur des lignes séparées.
i=0; declare -A myArray;
myArray+=( [red]=$((i++)) )
myArray+=( [orange]=$((i++)) )
myArray+=( [green]=$((i++)) )
echo ${myArray[green]}
2
Dites que vous voulez un tableau de chiffres et de lettres minuscules (par exemple: pour une sélection de menu), vous pouvez faites aussi quelque chose comme ça.
declare -a mKeys_1=( {{0..9},{a..z}} );
i=0; declare -A mKeys_1_Lookup; eval mKeys_1_Lookup[{{0..9},{a..z}}]="$((i++))";
Si vous exécutez alors
echo "${mKeys_1[15]}"
f
echo "${mKeys_1_Lookup[f]}"
15
J'aime cette solution:
let "n=(`echo ${myArray[@]} | tr -s " " "\n" | grep -n "green" | cut -d":" -f 1`)-1"
La variable n contiendra le résultat!
Cela pourrait juste fonctionner pour les tableaux,
my_array=(red orange green)
echo "$(printf "%s\n" "${my_array[@]}")" | grep -n '^orange$' | sed 's/:orange//'
Sortie:
2
Si vous voulez trouver l'index d'en-tête dans un fichier tsv,
head -n 1 tsv_filename | sed 's/\t/\n/g' | grep -n '^header_name$' | sed 's/:header_name//g'
Dans zsh vous pouvez faire
xs=( foo bar qux )
echo ${xs[(ie)bar]}
Voir Zshparam (1) sous-section indices
Un peu plus concis et fonctionne dans Bash 3.x:
my_array=(red orange green)
value='green'
for i in "${!my_array[@]}"; do
[[ "${my_array[$i]}" = "${value}" ]] && break
done
echo $i