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 que, na linha 13, o stdout está em branco, considerando que o array parece ter sido atualizado a julgar pelo stdout da linha 12?
E, portanto, o que devo fazer para obter a resposta pretendida, "69"?
Respostas:
unset
remove um elemento Não renumera os elementos restantes.Podemos usar
declare -p
para ver exatamente o que acontece comnumbers
:Observe que
numbers
não há mais um elemento4
.Outro exemplo
Observar:
A matriz
a
não possui elementos 2 a 21. O Bash não exige que os índices da matriz sejam consecutivos.Método sugerido para forçar uma renumeração dos índices
Vamos começar com a
numbers
matriz com o elemento ausente4
:Se gostaríamos que os índices mudassem, então:
Agora existe um número de elemento
4
e ele tem valor69
.Método alternativo para remover um elemento e renumerar uma matriz em uma etapa
Novamente, vamos definir
numbers
:Conforme sugerido por Toby Speight nos comentários, um método para remover o quarto elemento e renumerar os elementos restantes em uma única etapa:
Como você pode ver, o quarto elemento foi removido e todos os elementos restantes foram renumerados.
${numbers[@]:0:4}
matriz de fatiasnumbers
: leva os quatro primeiros elementos começando com o elemento 0.Da mesma forma,
${numbers[@]:5}
array de fatiasnumbers
: leva todos os elementos começando com o elemento 5 e continuando até o final do array.Obtendo os índices de uma matriz
Os valores de uma matriz podem ser obtidos com
${a[@]}
. Para encontrar os índices (ou chaves ) que correspondem a esses valores, use${!a[@]}
.Por exemplo, considere novamente nossa matriz
numbers
com o elemento ausente4
:Para ver quais índices estão atribuídos:
Novamente,
4
está faltando na lista de índices.Documentação
De
man bash
:fonte
a=()
, a variávela
ainda é indefinida até você realmente atribuir a um de seus índices.unset numbers[4]
atribuir toda a matriz usando o fatiamento, ou sejanumbers=("${numbers[@]:0:4}" "${numbers[@]:5}")
(eu postaria como resposta, mas não tenho tempo para explicar adequadamente).bash
matrizes como inksh
, não são realmente matrizes, são mais como matrizes associativas com chaves limitadas a números inteiros positivos (ou as chamadas matrizes esparsas ). Para um reservatório com matrizes reais, você pode dar uma olhada em escudos comorc
,es
,fish
,yash
,zsh
(ou mesmocsh
/tcsh
que essas conchas têm tantos problemas que eles estão melhor evitar).Em
zsh
:(Observe que, no zsh,
unset 'a[3]'
na verdade , o define como a sequência vazia para melhor compatibilidade comksh
)em
yash
:in
fish
(não é um shell tipo Bourne contrário abash
/zsh
):in
es
(baseado emrc
, não semelhante a Bourne)dentro
ksh
ebash
Você pode usar as matrizes como matrizes normais se:
depois de cada operação de exclusão ou inserção que possa ter tornado a lista de índices não contígua ou não iniciada em 0. Observe também que
ksh
/bash
matrizes iniciam em 0, não 1 (exceto$@
(de certa forma)).Com efeito, isso arrumará os elementos e os moverá para o índice 0, 1, 2 ... em sequência.
Observe também que você precisa citar o item
number[i]
em:Caso contrário, isso seria tratado como
unset numberi
se houvesse um arquivo chamadonumberi
no diretório atual.fonte