1

From what I've read on stack, here's one syntax :

iterator=0
while [ "$iterator" -lt 100 ]
do 
  printf "$iterator" 
  iterator=`expr $iterator + 1 `
done

Anybody cares to improve on this?

Aim is to make an iteration loop that would be most portable on posix systems.

[EDIT] just found this question which has very relevant answers: How do I iterate over a range of numbers defined by variables in Bash? but I'd like an answer here because I believe my question is more precise for future searches.

Community
  • 1
  • 1
mak
  • 1,384
  • 1
  • 13
  • 21
  • What do you want to iterate over? – melpomene Sep 04 '16 at 17:49
  • Integers. Here I'm using -lt 100 as an example. – mak Sep 04 '16 at 17:52
  • Possible duplicate of [How do I iterate over a range of numbers defined by variables in Bash?](http://stackoverflow.com/questions/169511/how-do-i-iterate-over-a-range-of-numbers-defined-by-variables-in-bash) – tripleee Sep 04 '16 at 19:13
  • We'd rather collect good answers in one place than have them scattered across many similar questions. The distinction between Bash and POSIX make this less cut and dried, but the nominated duplicate has many anwers which are portable, and are marked as such. – tripleee Sep 04 '16 at 19:18

2 Answers2

3
  • You probably want a newline in the printf format; otherwise, the numbers are all printed on a single line with no spacing.

  • You should use $(…) in place of the back-ticks.

  • Even POSIX shells support iterator=$(( $iterator + 1 )) (where the $(( … )) notation is distinct from the $( … ) notation!), so you don't need to use expr.

Putting those together:

iterator=0
while [ $iterator -lt 100 ]
do
    printf '%d\n' $iterator
    iterator=$(( $iterator + 1 ))
done

There are other options if you have a command such as seq available, but that isn't a part of POSIX.

There are those who would demand that the variables be enclosed in quotes when referenced. There's no harm in doing so, and in much general code, I would do so. But here the values are strictly controlled by the script; there is no way for blanks or other awkward characters to get in the way of the correct operation of the script.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • about the newline : yeah I kind of neglected that :) – mak Sep 04 '16 at 18:10
  • about `seq` : not POSIX indeed, and calling a subprocess, so don't want that. – mak Sep 04 '16 at 18:11
  • 2
    You didn't mind using sub-processes with the back-ticks and `expr`, so I'm not sure why `seq` would be a problem because it is a sub-process. Not POSIX is another issue altogether — and inescapable. But `awk 'BEGIN{for (i = 0; i < 100; i++) print i}` is impeccably POSIX, though still with a sub-process. – Jonathan Leffler Sep 04 '16 at 18:14
  • 1
    Incidentally, my answer is very close to the [answer](http://stackoverflow.com/a/31365662/15168) by [Ciro Santilli 巴拿馬文件 六四事件 法轮功](http://stackoverflow.com/users/895245/ciro-santilli-%e5%b7%b4%e6%8b%bf%e9%a6%ac%e6%96%87%e4%bb%b6-%e5%85%ad%e5%9b%9b%e4%ba%8b%e4%bb%b6-%e6%b3%95%e8%bd%ae%e5%8a%9f) in your cross-referenced question. – Jonathan Leffler Sep 04 '16 at 18:16
  • Yes, not using subprocesses is another thing. Let's not confuse stuff up. Btw, a closing quote is missing in you awk syntax. – mak Sep 04 '16 at 18:35
  • Yeah on the close quote. I spotted it over ten minutes later when it was uneditable. Sorry! – Jonathan Leffler Sep 04 '16 at 18:41
  • no worries, thanks for the great answer. I'm sure it's going to help people due to the specific title with usefull keywords. – mak Sep 04 '16 at 18:52
0

You could simply do...

while [ "$((iterator+=1))" -le 100 ]; do
    printf '%d\n' "$iterator"
done
IkuyoDev
  • 33
  • 4