Я хочу сделать что-то вроде этого:
foo=( )
foo[0]="bar"
foo[35]="baz"
for((i=0;i<${#foo[@]};i++))
do
echo "$i: ${foo[$i]}"
done
# Output:
# 0: bar
# 1:
Затем я попытался перебрать его, используя для в:
foo=( )
foo[0]="bar"
foo[35]="baz"
for i in ${foo[@]}
do
echo "?: $i"
done
# Output:
# ?: bar
# ?: naz
но здесь я не знаю значение индекса.
Я знаю, что ты мог что-то вроде
foo=( )
foo[0]="bar"
foo[35]="baz"
declare -p foo
# Output:
# declare -a foo='([0]="bar" [35]="baz")'
но вы не можете сделать это по-другому?
(a b c)
чтобы преобразовать в массив.[@]
и двойных кавычек означает, что это не «список слов, разделенных пробелами». Вы получите список фактических ключей массива, даже если отдельные ключи содержат пробелы.The use of [@] and double quotes means it's not a "space separated list of words"
"${foo[@]}"
берет переменную (массив)foo
и расширяет ее как массив, сохраняя идентичность его элементов, т. е. не разбивая их на пробелы. Еслиfoo=(x 'y z')
, тоf "${foo[@]}"
вызываетf
с двумя аргументами,x
и'y z'
. Запросы метаданных как"${!foo[@]}"
и"${#foo[@]}"
аналогично действуютfoo
как массив."${!foo[@]}"
это список всех индексов, установленных в массиве».вы всегда можете использовать итерационный параметр:
источник
((ITER++))
в современной башисточник
В bash 4 вы можете использовать ассоциативные массивы:
В bash 3 это работает (также работает в zsh):
источник
источник
Простой однострочный трюк для дампа массива
Я добавил одно значение с пробелами:
Я, для быстрого сброса удармассивы или ассоциативные массивы я использую
Эта однострочная команда:
Окажет:
Разъяснения
printf "%s\n" "${!foo[@]}"
напечатает все ключи, разделенные новой строкой ,printf "%s\n" "${foo[@]}"
напечатает все значения, разделенные новой строкой ,paste <(cmd1) <(cmd2)
объединит выводcmd1
иcmd2
построчно.Tunning
Это может быть настроено
-d
переключателем:или даже:
Ассоциативный массив будет работать так же:
Проблема с переводом строки или специальными
К сожалению, есть по крайней мере одно условие, заставляющее это больше не работать: когда переменная содержит символ новой строки:
Команда
paste
будет объединяться строка за строкой, поэтому вывод будет неправильным:Для этой работы вы можете использовать
%q
вместо%s
второйprintf
команды (и кавычки):Сделает идеально:
От
man bash
:источник
printf "%q\n" "${var[@]}"
перевод строки был моей проблемой!