La página de manual de Bash describe el uso de ${!a}
para devolver el contenido de la variable cuyo nombre es el contenido de a
(un nivel de indirección).
Me gustaría saber cómo devolver todos los elementos en una matriz usando esto, es decir,
a=(one two three)
echo ${a[*]}
devoluciones
one two three
Me gustaria para:
b=a
echo ${!b[*]}
para devolver lo mismo. Desafortunadamente, no lo hace, pero regresa en su 0
lugar.
Actualizar
Dadas las respuestas, ahora me doy cuenta de que mi ejemplo era demasiado simple, ya que, por supuesto, algo así como:
b=("${a[@]}")
Logrará exactamente lo que dije que necesitaba.
Entonces, esto es lo que estaba tratando de hacer:
LIST_lys=(lys1 lys2)
LIST_diaspar=(diaspar1 diaspar2)
whichone=$1 # 'lys' or 'diaspar'
_LIST=LIST_$whichone
LIST=${!_LIST[*]}
Por supuesto, leer cuidadosamente la página de manual de Bash muestra que esto no funcionará como se esperaba porque la última línea simplemente devuelve los índices de la "matriz" $_LIST
(no una matriz en absoluto).
En cualquier caso, lo siguiente debería hacer el trabajo (como se señaló):
LIST=($(eval echo \${$_LIST[*]}))
o ... (la ruta que tomé, eventualmente):
LIST_lys="lys1 lys2"
...
LIST=(${!_LIST})
Suponiendo, por supuesto, que los elementos no contienen espacios en blanco.
[@]
al puntero_LIST="LIST_${whichone}[@]"
y luego, useLIST=("${!_LIST}")
para copiar la matriz. Es una buena idea usar nombres de variables en minúsculas para evitar conflictos con las variables de entorno (mayúsculas).Respuestas:
Creo que el uso de la referencia indirecta de la variable bash debería tratarse literalmente.
P.ej. Para su ejemplo original:
Para el último escenario real, creo que el siguiente código haría el trabajo.
Es mejor usar notación
"${var[@]}"
que evite estropear la$IFS
expansión de parámetros y. Aquí está el código final.fuente
Necesita copiar los elementos explícitamente. Para una matriz indexada:
Para una matriz asociativa (tenga en cuenta que
a
es el nombre de la variable de matriz, no una variable cuyo valor es el nombre de una variable de matriz):Si tiene el nombre de la variable en una matriz, puede usar el método elemento por elemento con un paso adicional para recuperar las claves.
(Advertencia, el código de esta publicación se escribió directamente en un navegador y no se probó).
fuente
\${!$name[@]}
en la primera línea, de modo que la primera expansión sea solo de '$ name', y${!a[@]}
se guarde para la evaluación, y lo mismo en el ciclo for, con\${$name}
. Las otras dos barras invertidas antes de '$ k' tampoco son estrictamente necesarias allí.${!b[*]}
se expande a los índices utilizados en la matrizb
.Lo que le gustaría se tiene que hacer en dos pasos, por lo que
eval
le ayudará a:eval echo \${$b[*]}
. (Tenga en cuenta\
que garantiza que el primero$
pasará el primer paso, la expansión variable, y solo se expandirá en el segundo pasoeval
).Según el parámetro, la expansión
!
se usa para la expansión indirecta ({!a}
), el prefijo de coincidencia de nombres (${!a*}
) y la lista de teclas de matriz (${!a[*]}
). Debido a que la Lista de claves de matriz tiene la misma sintaxis que su expansión indirecta prevista + expansión de elemento de matriz, la última no es compatible como está.fuente
${!a}
se expande al valor de la variable cuyo nombre es$a
. Esto se describe de manera bastante tersa en el manual, en el párrafo que comienza con "Si el primer carácter del parámetro es un signo de exclamación (!
), se introduce un nivel de indirección variable".${!
es un poco ambiguo ya que si se trata de una matriz, el comportamiento es diferente.Para acceder a las matrices indirectamente, solo agregue
[@]
a la variable indirectab=a[@]
.Si se establecen estas variables:
Entonces, esto funcionará:
O simplemente:
Tal matriz podría copiarse así:
Y luego impreso con:
En un guión:
Por supuesto, todo lo anterior copiará una matriz no dispersa. Uno en el que todos los índices tienen un valor.
matrices dispersas
Una matriz dispersa es aquella que puede tener elementos no definidos.
Por ejemplo,
a[8]=1234
define un elemento y, en bash, 0 a 7 no existen.Para copiar dicha matriz dispersa, use este método
Imprima la matriz anterior:
Reemplace el nombre de la matriz y capture la cadena:
Evalúe la cadena así creada, se ha definido la nueva matriz:
fuente