Как добавить / удалить элемент в / из массива в Bash?


Ответы:


52

Чтобы добавить элемент в начало массива, используйте.

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

Чтобы добавить элемент к определенному индексу массива, используйте.

Допустим, мы хотим добавить элемент в позицию Index2 arr [2] , мы бы фактически слились с нижними подмассивами:

  1. Получить все элементы перед индексом position2 arr [0] и arr [1] ;
  2. Добавить элемент в массив;
  3. Получить все элементы с индексом position2 до последнего 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/}" )количество элементов не изменяется. Все, что он может сделать, это заменить их пустой строкой.
— Стефан Шазелас

так, чтобы удаляющая часть работала, нужно найти индекс, верно? какой самый быстрый способ найти его?
— qodeninja

3

Обратите внимание, что массивы в bash(скопированные из ksh) являются довольно ассоциативными массивами.

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

создаст новый $aмассив с newvalueas ${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")

Это объясняет, почему для этого нет встроенного оператора.

Если вы хотите вставить newvalueas ${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

Оболочки типа zshили yashс обычными массивами имеют операторы для этого:

  • zsh:

    a[1,0]=newvalue

    (также работает для добавления строк в скалярные переменные)

  • yash:

    array -i a 0 newvalue

1
"массивы в bash (скопированные из ksh) являются довольно ассоциативными массивами" ?? Я подумал, что в bash есть "регулярные" (возможно, разреженные) и ассоциативные (где вы можете использовать строки как индециты) массивы, чего мне не хватает?
— 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.