Uma coisa a ter em mente é que bash
implementou matrizes como ksh
, ou seja, matrizes associativas onde as chaves são limitadas a inteiros positivos (ao contrário de outras linguagens como perl
ou zsh
por exemplo).
Em:
a[123]=foo a[456]=bar a[789]=baz
No bash, você tem um array associativo com 3 elementos, enquanto que em perl
, você teria um array com 790 elementos (789 com zsh).
Em ksh
ou bash
, ${a[@]:0}
retorna o primeiro elemento da matriz na lista de elementos classificados por índices. Então, nesse caso, ele retorna ${a[123]}
, não ${a[0]}
.
unset 'a[123]'
(lembre-se de citar, senão ele falharia se houvesse um arquivo chamado a1 ou a2 ou a3 no diretório atual) faz sentido, já que remove uma chave particular na matriz.
unset 'a[@]::2'
faz menos sentido embora. bash
apenas entende unset a
, unset 'a[123]'
ou unset 'a[*/@]'
, qualquer coisa depois é ignorada, então unset 'a[@]::2'
e unset 'a[@]please'
fazem o mesmo: anule o array inteiro.
Se você deseja remover um intervalo de chaves, é necessário percorrer as teclas:
Para obter a lista de chaves da matriz, a sintaxe é "${!a[@]}"
. Infelizmente, aplicar um intervalo a isso não funciona com bash
nem ksh
, então você precisaria de um array temporário:
keys=("${!a[@]}")
for i in "${keys[@]::2}"; do unset "a[$i]"; done
Agora, se você quiser considerar esses arrays como em outros idiomas, não deseja usar unset
. Por exemplo, se a matriz não for escassa e você quiser mantê-la assim (ou seja, deslocar todos os elementos por 2 em vez de desativar os dois primeiros), é possível fazer coisas como:
a=("${a[@]:2}")
Isso é reatribuir o array com a lista de elementos que você deseja manter.
Para comparação, com zsh
.
a=({1..20})
unset 'a[12,16]'
definiria um valor vazio para os elementos 12 a 16. Enquanto unset 'a[16,20]'
reduziria o array para 15 elementos.
a=({1..20})
a[12,16]=()
(ainda com zsh
) mudaria os elementos 17 a 20 por 5 posições, então a[12]
conteria 17
.