Как сохранить диапазон в переменной для использования в цикле?

Как сохранить диапазон для использования в циклах?

Есть программа:

handshake=("wink" "double blink" "close your eyes" "jump")
code=$1
result=()

if ((code >> 4)); then
  for i in {3..0..-1}; do
    ((1 & (code >> i))) && result+=("${handshake[$i]}")
  done
else
  for i in {0..3}; do
    ((1 & (code >> i))) && result+=("${handshake[$i]}")
  done
fi

Хотелось бы переписать примерно так:

range=((code >> 4)) ? {3..0..-1} : {0..3}

for i in $range; do
  ((1 & (code >> i))) && result+=("${handshake[$i]}")
done

Как это правильно сделать в bash?


Ответы (1 шт):

Автор решения: aleksandr barakin

Хотелось бы переписать примерно так:

range=((code >> 4)) ? {3..0..-1} : {0..3}

тернарный оператор, конечно, присутствует в арсенале интерпретатора bash, но только при использовании арифметических вычислений:

переменная=$(( арифметическое-условие ? значение-если-да : значение-если-нет ))

т.е., результат может быть только числом.

если же результатом должна быть строка или массив, то придётся применять какую-нибудь из форм условного оператора. например:

if логическое-условие; then
  переменная=значение-если-да
else
  переменная=значение-если-нет
if

или

логическое-условие && переменная=значение-если-да || переменная=значение-если-нет

для вашего примера логическое условие может быть записано, например, так:

[ $((code >> 4)) == 1 ]

по поводу присвоения переменной последовательности значений.

если вы хотите итерацию в виде перебора значений в строке:

for i in $range

то и последовательность должна быть сохранен в виде строки. например:

переменная=$(echo {3..0..-1})

ещё можно сохранить последовательность в виде массива. например:

переменная=({3..0..-1})

тогда для итерации надо будет указывать именно массив:

for i in ${переменная[@]}
→ Ссылка