Jak dodać / usunąć element do / z tablicy w bash?


Odpowiedzi:


48

Aby dodać element na początku tablicy, użyj.

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

Zasadniczo zrobiłbyś.

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

Aby dodać element na końcu tablicy, użyj.

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

Lub zamiast tego

arr+=( "new_element" )

Zasadniczo zrobiłbyś.

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

Aby dodać element do określonego indeksu tablicy, użyj.

Powiedzmy, że chcemy dodać element do pozycji Index2 arr [2] , w rzeczywistości dokonalibyśmy scalenia na poniższych pod-tablicach:

  1. Zbierz wszystkie elementy przed Index position2 arr [0] i arr [1] ;
  2. Dodaj element do tablicy;
  3. Pobierz wszystkie elementy z indeksem position2 do ostatniego arr [2] , arr [3] , ....

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

Usuwanie elementu z tablicy

Oprócz usunięcia elementu z tablicy (powiedzmy element nr 2) musimy połączyć dwie pod-tablice. Pierwsza podtablica będzie przechowywać elementy przed elementem # 2, a druga pod-tablica będzie zawierać elementy po elemencie # 2.

arr=( "${arr[@]:0:2}" "${arr[@]:3}" )
  • ${arr[@]:0:2}otrzyma dwa elementy arr [0] i arr [1] zaczyna się od początku tablicy.
  • ${arr[@]:3}pobierze wszystkie elementy od indeksu 3 arr [3] do ostatniego.

Inną możliwością usunięcia elementu jest

  1. Używanie unset(faktycznie przypisanie wartości „null” do elementu)

    unset arr[2]
  2. Użyj zastępuj wzór, jeśli znasz wartość swoich elementów.

    arr=( "${arr[@]/PATTERN/}" )

2
Zauważ, że z wyjątkiem arr+=(element)i unset arr[2](które powinno być unset -v 'arr[2]'!), Które zakłada tablice nieliczne. Zauważ też, że arr=( "${arr[@]/PATTERN/}" )nie zmienia to liczby elementów. Wszystko, co może zrobić, to zastąpić je pustym ciągiem.
— Stéphane Chazelas

więc aby część usuwająca działała, musisz znaleźć indeks, prawda? jaki jest najszybszy sposób na znalezienie?
— qodeninja

3

Zauważ, że tablice w bash(skopiowane z ksh) są raczej tablicami asocjacyjnymi.

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

utworzy nową $atablicę z newvalueas ${a[0]}i elementy oryginalnej tablicy dołączone w kolejności numerycznej ich klawiszy za pomocą klawiszy 1, 2 ...

Na przykład, jeśli miałeś:

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

To wyjaśnia, dlaczego nie ma do tego wbudowanego operatora.

Jeśli chcesz wstawić newvalueas ${a[0]}i przesunąć wszystkie pozostałe klucze o jeden, potrzebujesz tymczasowej tablicy:

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

Powłoki podobne zshlub yashposiadające normalne tablice mają do tego operatory:

  • zsh:

    a[1,0]=newvalue

    (działa również w przypadku przygotowywania ciągów do zmiennych skalarnych)

  • yash:

    array -i a 0 newvalue

1
„Tablice w bash (skopiowane z ksh) są raczej tablicami asocjacyjnymi” ?? Myślałem, że w bashu są tablice „zwykłe” (być może rzadkie) i asocjacyjne (w których można używać łańcuchów jako indekii), czego mi brakuje?
— 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  
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.