Si j'ai un tableau avec 5 éléments, par exemple:
[a][b][c][d][e]
En utilisant echo ${myarray[4]}
Je peux voir ce qu'il contient.
Mais que se passe-t-il si je ne connais pas le nombre d'éléments dans un tableau donné? Existe-t-il un moyen de lire le dernier élément d'un tableau de longueur inconnue? c'est-à-dire le premier élément lisant de la droite vers la gauche pour n'importe quel tableau?
Je voudrais savoir comment faire cela en bash.
Vous pouvez simplement tiliser un indice négatif${myarray[-1]}
pour obtenir le dernier élément. Vous pouvez faire la même chose pour l'avant-dernier, et ainsi de suite; dans Bash:
Si l'indice utilisé pour référencer un élément d'un tableau indexé est évalué à un nombre inférieur à zéro, il est interprété comme étant relatif à un supérieur à l'indice maximal du tableau, de sorte que les indices négatifs comptent à rebours à partir de la fin du tableau et un l'indice de -1 fait référence au dernier élément.
Il en va de même pour l'affectation. Quand il dit "expression", cela signifie vraiment une expression; vous pouvez y écrire n'importe quelle expression arithmétique pour calculer l'index, y compris celle qui calcule en utilisant la longueur du tableau ${#myarray[@]}
explicitement.
Vous pouvez lire le dernier élément à l'index -1
:
$ a=(a b c d e f)
$ echo ${a[-1]}
f
Prise en charge de l'accès aux tableaux indexés numériquement depuis la fin à l'aide d'index négatifs commencé avec la version bash 4.1-alpha .
Vous devez obtenir la longueur du tableau à partir de ${#a[@]}
, Puis soustraire un pour obtenir le dernier élément:
$ echo ${a[${#a[@]}-1]}
f
Étant donné que bash traite les indices de tableau comme une expression arithmétique, aucune notation supplémentaire, telle que $((...))
, n'est nécessaire pour forcer l'évaluation arithmétique.
bash
l'attribution du tableau, la référence, la suppression avec un indice négatif n'étaient que ajouté dans bash 4. . Avec une ancienne version de bash
, vous pouvez utiliser l'expression dans l'index array[${#array[@]-1}]
Une autre façon, fonctionne également avec une ancienne version de bash
(bash 3.0 ou mieux):
$ a=([a] [b] [c] [d] [e])
$ printf %s\\n "${a[@]:(-1)}"
[e]
ou:
$ printf %s\\n "${a[@]: -1}"
[e]
En utilisant un décalage négatif, vous devez séparer :
avec -
pour éviter d'être confondu avec le :-
expansion.
La ou les alternatives les plus anciennes de bash (depuis bash 3.0+) sont:
$ a=(aa bb cc dd ee)
$ echo "${a[@]:(-1)} ${a[@]: -1} ${a[@]:(~0)} ${a[@]:~0}"
ee ee ee ee
L'espace est nécessaire pour éviter l'interprétation de :
suivi d'un moins -
comme l'expansion de "${var:-abc}"
(Utiliser les valeurs par défaut).
Le ~
est une arithmétique négation au niveau du bit (équivalent à son complément ou retourne tous les bits ). De l'homme bash:
ÉVALUATION ARITHMÉTIQUE
! ~ logical and bitwise negation
Depuis bash-4.2 + également:
$ echo "${a[-1]} ${a[(~0)]}"
ee ee
Depuis bash 5.0+ également:
$ echo "${a[~0]}"
ee
Pour toutes les versions bash (ancien bash):
$ echo "${a[ ${#a[@]}-1 ]}" # spaces added **only** for readability
ee
Pour les arguments positionnels (depuis bash 2.01):
$ set aa bb cc dd ee
$ echo "${@:(-1)} ${@:~0} ${@: -1} ${@:$#} ${!#}"
ee ee ee ee
Une solution portable pour tous les shells est d'utiliser eval:
eval printf '"%s\n"' \"\${$#}\"