¿Cómo agregar / eliminar un elemento a / de la matriz en bash?

Respuestas:

52

Para agregar un elemento al comienzo de una matriz, use.

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

En general, lo harías.

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

Para agregar un elemento al final de una matriz, use.

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

O en su lugar

arr+=( "new_element" )

En general, lo harías.

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

Para agregar un elemento al índice específico de una matriz use.

Digamos que queremos agregar un elemento a la posición de Index2 arr [2] , de hecho nos fusionaríamos en las siguientes sub-matrices:

  1. Obtenga todos los elementos antes del índice position2 arr [0] y arr [1] ;
  2. Agregue un elemento a la matriz;
  3. Obtenga todos los elementos con Index position2 hasta el último arr [2] , arr [3] , ....

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

Eliminar un elemento de la matriz

Además de eliminar un elemento de una matriz (digamos elemento # 2), necesitamos concatenar dos sub-matrices. La primera matriz secundaria contendrá los elementos antes del elemento # 2 y la segunda matriz secundaria contendrá los elementos después del elemento # 2.

arr=( "${arr[@]:0:2}" "${arr[@]:3}" )
  • ${arr[@]:0:2}obtendrá dos elementos arr [0] y arr [1] comienza desde el principio de la matriz.
  • ${arr[@]:3}obtendrá todos los elementos desde index3 arr [3] hasta el último.

Otra posibilidad para eliminar un elemento es

  1. Utilizando unset(en realidad asigne un valor 'nulo' al elemento)

    unset arr[2]
  2. Use el patrón de reemplazo si conoce el valor de sus elementos.

    arr=( "${arr[@]/PATTERN/}" )
αғsнιη
fuente
2
Tenga en cuenta que a excepción de arr+=(element)y unset arr[2](¡que debería ser unset -v 'arr[2]'!), Se asume que las matrices no son dispersas. También tenga en cuenta que arr=( "${arr[@]/PATTERN/}" )no cambia el número de elementos. Todo lo que puede hacer es reemplazarlos con la cadena vacía.
Stéphane Chazelas
entonces, para que la parte de eliminación funcione, debes encontrar el índice, ¿verdad? ¿Cuál es la forma más rápida de encontrarlo?
qodeninja
3

Tenga en cuenta que las matrices en bash(copiadas de ksh) son matrices más bien asociativas.

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

haría una nueva $amatriz con newvalueas ${a[0]}y los elementos de la matriz original adjuntos en el orden numérico de su clave con las teclas 1, 2 ...

Por ejemplo, si tuvieras:

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")

Eso explica por qué no hay un operador integrado para eso.

Si desea insertar el newvalueas ${a[0]}y cambiar todas las demás claves por una, necesitaría una matriz temporal:

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

Los shells como zsho yashque tienen matrices normales tienen operadores para eso:

  • zsh:

    a[1,0]=newvalue

    (también funciona para anteponer cadenas a variables escalares)

  • yash:

    array -i a 0 newvalue
Stéphane Chazelas
fuente
1
"Las matrices en bash (copiadas de ksh) son matrices más bien asociativas" ?? Pensé que hay arrays "regulares" (aunque posiblemente dispersos) y asociativos (donde puedes usar cadenas como indecies) en bash, ¿qué me estoy perdiendo?
NHED
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
fuente