web-dev-qa-db-fra.com

Existe-t-il un moyen de lire le dernier élément d'un tableau avec bash?

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.

74
3kstc

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.

97
Michael Homer

Bash moderne (v4.1 ou mieux)

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 .

Bash plus ancien (v4.0 ou antérieure)

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.

48
John1024

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.

15
cuonglm

tableau

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"' \"\${$#}\"
4
Isaac