Suchen Sie die Anzahl der Elemente im Array, auf die durch einen dynamisch erstellten Namen verwiesen wird

Suchen Sie die Anzahl der Elemente im Array, auf die durch einen dynamisch erstellten Namen verwiesen wird

Ich habe eine ähnliche Frage gefundenHier, aber es scheint nicht identisch zu sein, und keine der Antworten liefert die gewünschte Ausgabe. Ich habe ein Array, für das ich herausfinden möchte, wie viele Elemente es enthält, indem ich über einen dynamisch generierten Namen darauf zugreife.

declare -a array0=(2 4 2 5)  # contains 4 values
indx=0
Name="array$indx"            # create a name reference => array0

# I know how to obtain an indexed value by INDIRECT reference:
val0=${!Name[0]}
# I also know how to get array length using DIRECT name
len=${#array0[@]}

Ich muss die Anzahl der Elemente desArray0durch Referenzierung mittels VariableName

len=${#!Name[@]}             # the syntax is incorrect

Irgendwelche Vorschläge zur Umsetzung?

BEARBEITEN:
Ich habe mich geirrt, als ich sagte, dass man auf die Array-Einträge folgendermaßen zugreifen kann:

val0=${!Name[0]}

Dies funktioniert nur für indx=0. Wenn ich also andere Einträge aus dem Array abrufen möchte, wird einfach ein leerer String zurückgegeben:

val4=${!Name[4]}          #does not work

oder

i=4
val4=${!Name[$i]}         # does not work

Antwort1

Mit bash-4.3oder höher können Sie Namerefs verwenden:

a0=(a b c)
i=0
typeset -n Name="a$i"
echo "${#Name[@]}"

oder Sie können immerverwendeneval. Lassen Sie sich auf keinen Fall täuschen und denken, die Verwendung bashvon Namerefs seisichererals eval. Wie bei evalmüssen Sie immer noch sicherstellen, dass der Inhalt von $Nameein gültiger Shell-Variablenname ist. Werte wie x[`evil-command>&2`0]würden immer noch dazu führen, dass evil-commandausgeführt wird, wenn Sie $Nameoder erweitern ${#Name}. Gleiches gilt für ${!var}.

Mit ksh93könnten Sie stattdessen mehrdimensionale Arrays verwenden:

a[0]=(a b c)
i=0
echo "${#a[i][@]}"

zshhat konsistentere Möglichkeiten, seine Erweiterungsoperatoren zu kombinieren:

a0=(a b c)
i=0
name=a$i
echo ${(P)#name}

( Pfür indirekte Parametererweiterung).

Antwort2

Sie können es evalexplizit verwenden, aber übertreiben Sie es nicht:

eval "len=\${#$Name[@]}"

verwandte Informationen