The way to iterate over a range in bash is
for i in {0..10}; do echo $i; done What would be the syntax for iterating over the sequence with a step? Say, I would like to get only even number in the above example.
The way to iterate over a range in bash is
for i in {0..10}; do echo $i; done What would be the syntax for iterating over the sequence with a step? Say, I would like to get only even number in the above example.
I'd do
for i in `seq 0 2 10`; do echo $i; done (though of course seq 0 2 10 will produce the same output on its own).
Note that seq allows floating-point numbers (e.g., seq .5 .25 3.5) but bash's brace expansion only allows integers.
Bash 4's brace expansion has a step feature:
for {0..10..2}; do .. done No matter if Bash 2/3 (C-style for loop, see answers above) or Bash 4, I would prefer anything over the 'seq' command.
i, then you can't do for {0..10..${i}} .. it fails.Pure Bash, without an extra process:
for (( COUNTER=0; COUNTER<=10; COUNTER+=2 )); do echo $COUNTER done {0..10..2}-style, e.g. when the range is really large.#!/bin/bash for i in $(seq 1 2 10) do echo "skip by 2 value $i" done brace expansion {m..n..s} is more efficient than seq. AND it allows a bit of output formatting:
$ echo {0000..0010..2} 0000 0002 0004 0006 0008 0010 which is useful if one numbers e.g. files and want's a sorted output of 'ls'.
echo $((020+001)) which prints 17, where echo {000..020..002} prints 000 002 004 006 008 010 012 014 016 018 020Often, it is desirable to use that sequence as an array. I suggest the following function:
sh_range(){ local from="$1" local to="$2" local -n _sh_range_out="$3" local i _sh_range_out=() for((i=$from; i<=$to; i++)); do _sh_range_out+=("$i") done } sh_range 1 3 array declare -p array >>> declare -a array=([0]="1" [1]="2" [2]="3") I will be a little repetitive, but no other answer mentions that the built-in `seq` command can be used with a custom format to print the sequence. I discovered it as I was about to write a helper to give me that and was glad it was not needed after all :)
seq -f "Foo %g" 3 # Prints "Foo 1", "Foo 2", "Foo 3", each on separate line The options must come first, i.e. seq [OPTIONS...] [FIRST [INCREMENT]] LAST with the first number and increment being both optional. The numbers can also be floats, and then %.3f can be used in formatting, where 3 is the decimal precision.
Other useful options are -s "," to specify a custom separator (default to a new line), and -w to pad the numbers with leading zeros for a fixed width (cannot be used together with -f).