1 #!/bin/bash
2 # query2.sh
3
4 numbers=(53 8 12 9 784 69 8 7 1)
5 i=4
6
7 echo ${numbers[@]} # <--- this echoes "53 8 12 9 784 69 8 7 1" to stdout.
8 echo ${numbers[i]} # <--- this echoes "784" to stdout.
9
10 unset numbers[i]
11
12 echo ${numbers[@]} # <--- this echoes "53 8 12 9 69 8 7 1" to stdout.
13 echo ${numbers[i]} # <--- stdout is blank.
¿Por qué, en la línea 13, el stdout está en blanco, considerando que la matriz parece haberse actualizado a juzgar por el stdout de la línea 12?
Y por lo tanto, ¿qué debo hacer para obtener la respuesta deseada, "69"?
Respuestas:
unset
elimina un elemento No renumera los elementos restantes.Podemos usar
declare -p
para ver exactamente qué sucede connumbers
:Observe que
numbers
ya no tiene un elemento4
.Otro ejemplo
Observar:
La matriz
a
no tiene elementos del 2 al 21. Bash no requiere que los índices de la matriz sean consecutivos.Método sugerido para forzar una nueva numeración de los índices.
Comencemos con la
numbers
matriz con el elemento que falta4
:Si queremos que cambien los índices, entonces:
Ahora hay un número de elemento
4
y tiene valor69
.Método alternativo para eliminar un elemento y renumerar la matriz en un solo paso
Nuevamente, definamos
numbers
:Como lo sugiere Toby Speight en los comentarios, un método para eliminar el cuarto elemento y volver a numerar los elementos restantes en un solo paso:
Como puede ver, el cuarto elemento se eliminó y todos los elementos restantes se volvieron a numerar.
${numbers[@]:0:4}
matriz de rebanadasnumbers
: toma los primeros cuatro elementos comenzando con el elemento 0.Del mismo modo,
${numbers[@]:5}
matriz de cortenumbers
: toma todos los elementos que comienzan con el elemento 5 y continúan hasta el final de la matriz.Obteniendo los índices de una matriz
Los valores de una matriz se pueden obtener con
${a[@]}
. Para encontrar los índices (o claves ) que corresponden a esos valores, use${!a[@]}
.Por ejemplo, considere nuevamente nuestra matriz
numbers
con el elemento que falta4
:Para ver qué índices se asignan:
Nuevamente,
4
falta en la lista de índices.Documentación
De
man bash
:fuente
a=()
, la variablea
aún no está definida hasta que realmente asigne uno de sus índices.unset numbers[4]
asignar toda la matriz usando la división, es decirnumbers=("${numbers[@]:0:4}" "${numbers[@]:5}")
(publicaría como respuesta, pero no tengo tiempo para explicarlo adecuadamente).bash
Las matrices como enksh
, no son realmente matrices, son más bien matrices asociativas con claves limitadas a enteros positivos (o llamadas matrices dispersas ). Para un depósito con matrices reales, se puede echar un vistazo a como conchasrc
,es
,fish
,yash
,zsh
(o inclusocsh
/tcsh
aunque esos proyectiles tienen tantos problemas que están mejor evitado).En
zsh
:(Tenga en cuenta que en zsh, en
unset 'a[3]'
realidad lo establece en la cadena vacía para mejorar la compatibilidad conksh
)en
yash
:en
fish
(no un shell Bourne contrario abash
/zsh
):en
es
(basado enrc
, no como Bourne)en
ksh
ybash
Puede usar las matrices como matrices normales si hace lo siguiente:
después de cada operación de eliminación o inserción que puede haber hecho que la lista de índices no sea contigua o no comience en 0. También tenga en cuenta que
ksh
/bash
arrays comienzan en 0, no en 1 (excepto$@
(en algunos aspectos)).De hecho, eso ordenará los elementos y los moverá al índice 0, 1, 2 ... en secuencia.
También tenga en cuenta que necesita citar el
number[i]
en:De lo contrario, eso se trataría como si
unset numberi
hubiera un archivo llamadonumberi
en el directorio actual.fuente