
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.3
oder 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 bash
von Namerefs seisichererals eval
. Wie bei eval
müssen Sie immer noch sicherstellen, dass der Inhalt von $Name
ein gültiger Shell-Variablenname ist. Werte wie x[`evil-command>&2`0]
würden immer noch dazu führen, dass evil-command
ausgeführt wird, wenn Sie $Name
oder erweitern ${#Name}
. Gleiches gilt für ${!var}
.
Mit ksh93
könnten Sie stattdessen mehrdimensionale Arrays verwenden:
a[0]=(a b c)
i=0
echo "${#a[i][@]}"
zsh
hat konsistentere Möglichkeiten, seine Erweiterungsoperatoren zu kombinieren:
a0=(a b c)
i=0
name=a$i
echo ${(P)#name}
( P
für indirekte Parametererweiterung).
Antwort2
Sie können es eval
explizit verwenden, aber übertreiben Sie es nicht:
eval "len=\${#$Name[@]}"