-1

I would like to save a range in a variable to use it later in for loop.

I have the code:

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

I would like to re-write the construction like:

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

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

How to do this in bash?

Jegors Čemisovs
  • 608
  • 6
  • 14

2 Answers2

1

A for loop with an immediate sequence expression works as expected:

for abc in {0..3}; do echo $abc; done

A for loop with a $var that contains a sequence expression needs another expansion:

#!/bin/bash

if [ $# -eq 0 ]; then
    echo missing arg
    exit 1
else
    code=$1
fi

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

[[ $((code >> 4)) != 0 ]] && range={3..0} || range={0..3}

echo range: \"$range\"

echo -e "\nloop:"
for abc in $(eval echo $range); do
    echo -n "$abc "
done
echo

There's more SO discussion here

Milag
  • 1,793
  • 2
  • 9
  • 8
1

I found one of the possible solutions.

#!/usr/bin/env bash

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

((code >> 4)) && range=({3..0}) || range=({0..3})

for i in "${range[@]}"; do
  if ((1 & (code >> i))); then
    [[ -n $result ]] && result+=","
    result+="${handshake[$i]}"
  fi
done

echo "$result"
Jegors Čemisovs
  • 608
  • 6
  • 14