¿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/}" )

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

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  
}
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.