Преобразование цикла for в цикл while if fi UNIX

Я пытаюсь понять, как преобразовать следующий цикл for в цикл while или циклuntil, включая if fi для UNIX. Вот код...

#!/bin/bash

if [ $# -gt 0 ] ; then 
  start=$1
 end=$3
 step=$2

 for x in `seq $start $step $end` ; do
  number $x
  done

else
 echo Enter at least one number on the command line.

fi

Любая помощь приветствуется!


person user2329706    schedule 28.04.2013    source источник


Ответы (4)


Для такого цикла проще всего использовать числовой цикл for:

for ((x=start; x<=end; x+=step)); do
    number $x
done
person Gordon Davisson    schedule 28.04.2013

Использование seq хорошо, поскольку у него есть некоторые значения по умолчанию для значений step и end. Я добавил это в if, если задан только один или два аргумента. Также он обрабатывает ситуацию, если данный аргумент не является числом (значения по умолчанию равны 0). Также может возникнуть бесконечный цикл, если step равно нулю. Если вы удалите эту проверку, она будет работать так же, как и версия seq.

if [ $# -gt 0 ] ; then
  x=$(($1+0))
  end=$((${3:-$x}+0))
  step=$((${2:-1}+0))

  [ $step -eq 0 ] && echo "Step is zero!" && exit 1

  while [ $x -le $end -a $step -gt 0 -o $x -ge $end -a $step -lt 0 ]; do
    echo $x
    x=$((x+step))
  done

else
   echo Enter at least one number on the command line.
fi

Измените echo на number в цикле while, если хотите использовать!

Примеры:

$ ./e.sh 1    
1
$ seq 1
1
$ ./e.sh 1 1 3
1
2
3
$ seq 1 1 3
1
2
3
$ ./e.sh 1 -1 3
$ seq 1 -1 3
$ ./e.sh 3 -1 1
3
2
1
$ seq 3 -1 1
3
2
1
$ ./e.sh 1 0 1 
Step is zero!
$ seq 1 0 1|head 
1
1
1
... (endlessly)
$ ./e.sh 1 .1 1.2
./e.sh: line 3: 1.2+0: syntax error: invalid arithmetic operator (error token is ".2+0")
$ seq 1 .1 1.2
1.0
1.1
1.2

Арифметика Bash не работает с числами с плавающей запятой, но seq работает. Если вам нужна эта функция, вы можете использовать формат x=$(echo $x + $step|bc). Также $((...)) следует заменить на $(...|bc) подобных строк.

person TrueY    schedule 29.04.2013
comment
@ user2329706: Я рад, если смог помочь. Я предлагаю вам использовать оригинальную версию seq. - person TrueY; 29.04.2013

В Bash 4 вы также можете сделать это так:

for i in {$start..$stop..$step}; do
    echo $i
done
person tamasgal    schedule 29.04.2013

person    schedule
comment
Если step равно -1, это может привести к результатам, отличным от последовательностей. - person TrueY; 29.04.2013