Como adicionar / remover um elemento para / da matriz no bash?

Respostas:

50

Para adicionar um elemento ao início de uma matriz, use.

arr=("new_element" "${arr[@]}")

Geralmente, você faria.

arr=("new_element1" "new_element2" "..." "new_elementN" "${arr[@]}")

Para adicionar um elemento ao final de uma matriz, use.

arr=( "${arr[@]}" "new_element" )

Ou então

arr+=( "new_element" )

Geralmente, você faria.

arr=( "${arr[@]}" "new_element1" "new_element2" "..." "new_elementN") #Or
arr+=( "new_element1" "new_element2" "..." "new_elementN" )

Para adicionar um elemento ao índice específico de uma matriz, use.

Digamos que queremos adicionar um elemento à posição do Index2 arr [2] , na verdade, nos fundiremos abaixo das sub-matrizes:

  1. Obtenha todos os elementos antes do índice position2 arr [0] e arr [1] ;
  2. Adicione um elemento à matriz;
  3. Obtenha todos os elementos com a posição Index2 até o último arr [2] , arr [3] , ....

    arr=( "${arr[@]:0:2}" "new_element" "${arr[@]:2}" )

Removendo um elemento da matriz

Além de remover um elemento de uma matriz (digamos o elemento 2), precisamos concatenar duas sub-matrizes. O primeiro sub-array reterá os elementos antes do elemento 2 e o segundo sub-array conterá os elementos após o elemento 2.

arr=( "${arr[@]:0:2}" "${arr[@]:3}" )
  • ${arr[@]:0:2}receberá dois elementos arr [0] e arr [1] começa no início da matriz.
  • ${arr[@]:3}irá obter todos os elementos do index3 arr [3] para o último.

Outra possibilidade de remover um elemento é

  1. Usando unset(na verdade, atribua valor 'nulo' ao elemento)

    unset arr[2]
  2. Use o padrão de substituição se você souber o valor de seus elementos.

    arr=( "${arr[@]/PATTERN/}" )
αғsнιη
fonte
2
Note-se que, exceto para o arr+=(element)e unset arr[2](que deve ser unset -v 'arr[2]'!), Que assume matrizes não-esparsos. Observe também que o arr=( "${arr[@]/PATTERN/}" )não altera o número de elementos. Tudo o que pode fazer é substituí-los pela string vazia.
Stéphane Chazelas
então, para que a peça removida funcione, você precisa encontrar o índice, certo? qual é a maneira mais rápida de encontrá-lo?
qodeninja 25/08
3

Observe que matrizes bash(copiadas do ksh) são matrizes bastante associativas.

a=(newvalue "$a[@]")

criaria uma nova $amatriz com newvalueas ${a[0]}e os elementos da matriz original anexados na ordem numérica de sua chave com as teclas 1, 2 ...

Por exemplo, se você tivesse:

bash-4.4$ typeset -p a
declare -a a=([0]="foo" [12]="bar")
bash-4.4$ a=(newvalue "${a[@]}")
bash-4.4$ typeset -p a
declare -a a=([0]="newvalue" [1]="foo" [2]="bar")

Isso explica por que não há um operador interno para isso.

Se você deseja inserir o newvalueas ${a[0]}e mudar todas as outras chaves por uma, precisará de uma matriz temporária:

b=newvalue
for k in "${!a[@]}"; do
  b[k+1]=${a[k]}
done
unset a
for k in "${!b[@]}"; do
  a[k]=${b[k]}
done
unset b

Os shells como zshou yashque possuem matrizes normais têm operadores para isso:

  • zsh:

    a[1,0]=newvalue

    (também funciona para anexar sequências a variáveis ​​escalares)

  • yash:

    array -i a 0 newvalue
Stéphane Chazelas
fonte
1
"matrizes no bash (copiadas do ksh) são matrizes bastante associativas"? Eu pensei que há matrizes "regulares" (embora possivelmente escassas) e associativas (onde você pode usar cadeias de caracteres como indecies) no bash, o que estou perdendo?
nhed 26/09
0
# array declaration  
arr=()  

#Function to read data from file a and add into array  
fun_add_in_array()
{  
input=$1  
while IFS=',' read -r f1 f2  
do  
    echo "Element1 : $f1"  
    echo "Element2 : $f2"  
    arr+=( "$f1" )  
done < "$input"  
}  

#Function to print a array  
fun_read_array()  
{  
arr=("$@")  
for i in "${arr[@]}"  
do  
    echo $i  
done  
}
Mahendra
fonte