Як додати / видалити елемент до / з масиву в 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.