У меня есть динамический массив со значениями пары ключей, и я хотел бы перечислить все остальные значения. В этом случае просто имена в массиве. Поскольку я не использую bash v4, я смог использовать seq для перехода по массиву с помощью echo.

$ array=(Guido yes Francesca no Balthazar yes)
for x in $(seq 0 2 ${#array[@]});do echo $x;done
0
2
4
6

Это возвращает на один элемент больше, чем у моих пар (из-за смещения 0), но я могу объяснить это с помощью простой математики bash:

for x in $(seq 0 2 $((${#array[@]}-1)));do echo $x;done
0
2
4

Это работает просто отлично. Но как только я пытаюсь извлечь элементы из $array , я получаю ошибку, которую не могу объяснить. Я пробовал с и без "математики"

$ for x in $(seq 0 2 $((${#array[@]}-1)));do echo ${array[$x]};done
-bash: 0: syntax error: operand expected (error token is "0")

$ for x in $(seq 0 2 ${#array[@]});do echo ${array[$x]};done
-bash: 0: syntax error: operand expected (error token is "0")

Как я могу получить только имена из этого динамического массива?

РЕДАКТИРОВАТЬ: мой $BASH_VERSION является 3.2.57(1)-release (Mac OS X 10.10.2)

РЕДАКТИРОВАТЬ # 2: я пришел к выводу, что это возможно ошибка в этой версии. Поскольку я управляю несколькими экземплярами AWS, я решил проверить их, и все они имеют bash 4.1.2(1). Я обновил свой Mac до этой версии, и теперь это работает. Спасибо за просмотр, но я говорю это до аномалии.

1 ответ1

2

Если вы хотите перебрать альтернативные элементы массива, этот должен работать на bash 3.2:

while IFS= read -d '' -r name; do
  # do something with "$name"
done < <(printf %s%.0s\\0 "${array[@]}")

Вы можете делать подобные вещи с xargs -0 если это более удобно.

Если ни одно из ваших имен не содержит двоеточия (например), вы можете извлечь имена в новый массив, например так:

IFS=: read -a names -r < <(printf %s%.0s: "${array[@]}")

(К сожалению, вы не можете установить разделитель полей в NUL.)

Все это зависит от того факта, что printf повторяет свою строку формата так часто, как это необходимо для использования всех ее аргументов (поведение Posix, поэтому оно должно работать на любой версии bash или с не встроенным printf). Иногда используемый формат %.0s использует аргумент и выводит не более 0 символов из него, то есть сбрасывает его в битовую корзину.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .