Як додати / видалити елемент до / з масиву в bash?


Відповіді:


50

Щоб додати елемент до початку масиву, використовуйте.

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

Взагалі, ви б зробили.

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

Щоб додати елемент до кінця масиву, використовуйте.

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

Або замість цього

arr+=( "new_element" )

Взагалі, ви б зробили.

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

Щоб додати елемент до певного індексу масиву, використовуйте.

Скажімо, ми хочемо додати елемент до позиції arr Index2 [2] , ми насправді зробимо об'єднання на нижчих підмасивах :

  1. Отримати всі елементи до позиції Index2 arr [0] та arr [1] ;
  2. Додайте елемент до масиву;
  3. Отримайте всі елементи з позицією Index2 до останньої arr [2] , arr [3] , ....

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

Видалення елемента з масиву

Крім видалення елемента з масиву (скажімо, елемента №2), нам потрібно об'єднати два підмасиви. Перший підмасив буде містити елементи перед елементом №2, а другий масив буде містити елементи після елемента №2.

arr=( "${arr[@]:0:2}" "${arr[@]:3}" )
  • ${arr[@]:0:2}отримає два елементи arr [0], а arr [1] починається з початку масиву.
  • ${arr[@]:3}отримає всі елементи від index3 arr [3] до останнього.

Інша можливість видалити елемент - це

  1. Використання unset(фактично призначити елементу значення "null")

    unset arr[2]
  2. Використовуйте шаблон заміни, якщо ви знаєте цінність своїх елементів.

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

2
Зауважте, що за винятком arr+=(element)і unset arr[2](що має бути unset -v 'arr[2]'!), Що передбачає нерозріджені масиви. Також зауважте, що arr=( "${arr[@]/PATTERN/}" )кількість елементів не змінюється. Все, що він може зробити, це замінити їх порожнім рядком.
— Stéphane Chazelas

тож для того, щоб виймальна частина працювала, ви повинні знайти індекс, правда? який найшвидший спосіб її знайти?
— qodeninja

3

Зауважте, що масиви в bash(скопійовані з ksh) є досить асоціативними масивами.

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

зробить новий $aмасив з newvalueяк ${a[0]}і елементи вихідного масиву, додані в числовому порядку їх ключа з клавішами 1, 2 ...

Наприклад, якщо у вас були:

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

Це пояснює, чому для цього немає вбудованого оператора.

Якщо ви хочете вставити newvalueяк ${a[0]}і перемістити всі інші клавіші на одну, вам знадобиться тимчасовий масив:

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

Оболонки, якi zshабо yashмають нормальний масив, мають оператори для цього:

  • zsh:

    a[1,0]=newvalue

    (також працює для попереднього додавання рядків до скалярних змінних)

  • yash:

    array -i a 0 newvalue

1
"масиви в bash (скопійовані з ksh) є досить асоціативними масивами" ?? Я подумав, що в баші є "регулярні" (можливо, рідкісні) та асоціативні (де ви можете використовувати рядки як індексації), що мені не вистачає?
— 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  
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.