Ответ 1
a=(foo bar "foo 1" "bar two") #create an array
b=("${a[@]}") #copy the array in another one
for value in "${b[@]}" ; do #print the new array
echo "$value"
done
У меня есть массив приложений, инициализированных так:
depends=$(cat ~/Depends.txt)
Когда я пытаюсь разобрать список и скопировать его в новый массив, используя,
for i in "${depends[@]}"; do
if [ $i #isn't installed ]; then
newDepends+=("$i")
fi
done
Что происходит, так это то, что только первый элемент зависит от newDepends.
for i in "${newDepends[@]}"; do
echo $i
done
^^ Это выведет только одну вещь. Поэтому я пытаюсь понять, почему мой цикл for только перемещает первый элемент. Весь список изначально зависит, так что это не так, но у меня нет идей.
a=(foo bar "foo 1" "bar two") #create an array
b=("${a[@]}") #copy the array in another one
for value in "${b[@]}" ; do #print the new array
echo "$value"
done
Самый простой способ скопировать неассоциативный массив в bash - это:
arrayClone=("${oldArray[@]}")
или добавить элементы в предсуществующий массив:
someArray+=("${oldArray[@]}")
Новые строки/пробелы/IFS в элементах будут сохранены.
Для копирования ассоциативных массивов решения Isaac отлично работают.
Решения, указанные в других ответах, не будут работать для ассоциативных массивов или для массивов с несмежными индексами. Вот более общее решение:
declare -A arr=([this]=hello [\'that\']=world [theother]='and "goodbye"!')
temp=$(declare -p arr)
eval "${temp/arr=/newarr=}"
diff <(echo "$temp") <(declare -p newarr | sed 's/newarr=/arr=/')
# no output
И еще:
declare -A arr=([this]=hello [\'that\']=world [theother]='and "goodbye"!')
declare -A newarr
for idx in "${!arr[@]}"; do
newarr[$idx]=${arr[$idx]}
done
diff <(echo "$temp") <(declare -p newarr | sed 's/newarr=/arr=/')
# no output
Начиная с Bash 4.3, вы можете сделать это
$ alpha=(bravo charlie 'delta 3' '' foxtrot)
$ declare -n golf=alpha
$ echo "${golf[2]}"
delta 3
Вы можете скопировать массив, вставив элементы первого массива в копию, указав индекс:
#!/bin/bash
array=( One Two Three Go! );
array_copy( );
let j=0;
for (( i=0; i<${#array[@]}; i++)
do
if [[ $i -ne 1 ]]; then # change the test here to your 'isn't installed' test
array_copy[$j]="${array[$i]}
let i+=1;
fi
done
for k in "${array_copy[@]}"; do
echo $k
done
Результатом этого будет:
One
Three
Go!
Полезный документ на bash массивах находится на TLDP.
Проблема в том, чтобы скопировать массив в функцию, чтобы он был виден в родительском коде. Это решение работает для индексированных массивов и, если перед копированием предварительно определены как declare -A ARRAY
, работает также для ассоциативных массивов.
function array_copy
# $1 original array name
# $2 new array name with the same content
{
local INDEX
for INDEX in $(eval echo "\${!$1[@]}")
do
eval "$2[\"$INDEX\"]=\"\${$1[$INDEX]}\""
done
}
Попробуйте это: arrayClone=("${oldArray[@]}")
Это работает легко.
Я обнаружил, что не так. Мой тест if not installed is two для циклов, которые удаляют лишние символы из имен файлов и выплевывает их, если они существуют на определенном веб-сервере. То, что он не делал, - это удаление конечного дефиса. Итак, когда он протестировал его онлайн для доступности, они были разобраны. Потому что "файл" существует, но "file-" не работает.