Shell script "для" синтаксиса цикла

У меня есть следующее:

for i in {2..10}
do
    echo "output: $i"
done

Он создает пучок строк output: 2, output: 3 и так далее.

Однако, попробуйте запустить следующее:

max=10
for i in {2..$max}
do
    echo "$i"
done

выдает следующее:

output: {2..10}

Как я могу заставить компилятор понять, что он должен обрабатывать $max как другой конец массива, а не часть строки?

Ответ 1

Расширение скобки, {x..y} выполняется перед другими расширениями, поэтому вы не можете использовать это для последовательностей переменной длины.

Вместо этого используйте метод seq 2 $max, как указано mobrule.

Итак, для вашего примера это будет:

max=10
for i in `seq 2 $max`
do
    echo "$i"
done

Ответ 2

Попробуйте версию арифметического выражения for:

max=10
for (( i=2; i <= $max; ++i ))
do
    echo "$i"
done

Это доступно в большинстве версий bash и должно быть совместимо с оболочкой Bourne (sh).

Ответ 3

Настройте цикл вручную:

i=0
max=10
while [ $i -lt $max ]
do
    echo "output: $i"
    true $(( i++ ))
done

Если вам не нужно полностью POSIX, вы можете использовать арифметику для цикла:

max=10
for (( i=0; i &lt max; i++ )); do echo "output: $i"; done

Или используйте jot (1) в BSD-системах:

for i in $( jot 0 10 ); do echo "output: $i"; done

Ответ 4

Доступна ли команда seq в вашей системе?

for i in `seq 2 $max`
do
  echo "output: $i"
done

ИЗМЕНИТЬ: Нет seq? Тогда как насчет бедного человека seq с perl?

seq=`perl -e "\$,=' ';print 2..$max"`
for i in seq
do
  echo "output: $i"
done

Смотрите эти кавычки.

Ответ 5

Здесь более одного способа сделать это.

max=10
for i in `eval "echo {2..$max}"`
do
    echo "$i"
done

Ответ 6

Это способ:
Bash:

max=10
for i in $(bash -c "echo {2..${max}}"); do echo $i; done

Вышеупомянутый способ Bash будет работать и для ksh и zsh, когда bash -c заменяется на ksh -c или zsh -c соответственно.

Примечание: for i in {2..${max}}; do echo $i; done работает в zsh и ksh.

Ответ 7

Здесь он работал на MAC-OS // Он включает пример даты BSD, как увеличивать и уменьшать дату также

for ((i=28; i>=6 ; i--));
do
dat=`date -v-${i}d -j "+%Y%m%d"` 
echo $dat
done

Ответ 8

Все они выполняют {1..8} и должны быть POSIX. Они также не сломаются, если вы поместите условный continue в цикл. Канонический путь:

f=
while [ $((f+=1)) -le 8 ]
do
  echo $f
done

Другой способ:

g=
while
  g=${g}1
  [ ${#g} -le 8 ]
do
  echo ${#g}
done

а другой:

set --
while
  set $* .
  [ ${#} -le 8 ]
do
  echo ${#}
done

Ответ 9

Ну, так как у меня не было команды seq, установленной в моей системе (Mac OS 10.6.1), я вместо этого использовал цикл while:

max=5
i=1

while [ $max -gt $i ]
do
    (stuff)
done

* пожимает плечами * Все, что работает.

Ответ 10

как насчет

max=10
for i in `eval echo {2..$max}`
do
    echo $i
done

Вам нужен явный вызов eval для переоценки {} после замены переменной