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 < 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 для переоценки {} после замены переменной