Как добавить / удалить элемент в / из массива в 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/}" )
αғsнιη
источник
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  
}
Мээндра
источник