Вопрос о назначении массивов переменным в bash script представляется довольно сложным:
a=("a" "b" "c")
b=$a
echo ${a[0]}
echo ${a[1]}
echo ${b[0]}
echo ${b[1]}
приводит к
a
b
a
вместо
a
b
a
b
Почему? Как я могу это исправить?
Вопрос о назначении массивов переменным в bash script представляется довольно сложным:
a=("a" "b" "c")
b=$a
echo ${a[0]}
echo ${a[1]}
echo ${b[0]}
echo ${b[1]}
приводит к
a
b
a
вместо
a
b
a
b
Почему? Как я могу это исправить?
Если вы хотите переназначить переменную, содержащую массив, для другого имени, выполните следующее:
a=('a' 'b' 'c')
b=( "${a[@]}" )
Если a
- это массив, $a
расширяется до первого элемента массива. Вот почему b
в вашем примере имеет только одно значение. В bash переменные, относящиеся к массивам, не могут быть назначены, как указатели, в С++ или Java. Вместо этого переменные расширяются (как в разделе "Расширение параметров" ) в строки, и эти строки копируются и связаны с назначаемой переменной.
Чтобы скопировать разреженный массив, содержащий значения с пробелами, массив должен быть скопирован по одному элементу за раз по индексам - который можно получить с помощью ${! a [@]}.
declare -a b=()
for i in ${!a[@]}; do
b[$i]="${a[$i]}"
done
На странице bash man:
Можно получить ключи (индексы) массива, а также значения. ${! name [@]} и ${! name [*]} развернуть индексы, назначенные в имени переменной массива. Лечение, когда в двойных кавычках похоже на расширение специального параметры @и * в двойных кавычках.
Здесь script вы можете протестировать самостоятельно:
#!/bin/bash
declare -a a=();
a[1]='red hat'
a[3]='fedora core'
declare -a b=();
# Copy method that works for sparse arrays with spaces in the values.
for i in ${!a[@]}; do
b[$i]="${a[$i]}"
done
# does not work, but as LeVar Burton says ...
#b=("${a[@]}")
echo a indicies: ${!a[@]}
echo b indicies: ${!b[@]}
echo "values in b:"
for u in "${b[@]}"; do
echo $u
done
Печать
a indicies: 1 3
b indicies: 1 3 # or 0 1 with line uncommented
values in b:
red hat
fedora core
Это также работает для ассоциативных массивов в bash 4, если вы используете declare -A
(с капиталом A вместо строчного) при объявлении массивов.