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.