Here's a simple trick that uses the (relatively obscure) variable expansion and substring replacement capabilities of the shell.
#!/bin/bash
v_range="1..3" # or you could have taken it as a script parameter
v_start=${v_range%%.*} # chomp everything from the left-most matching "."
v_end=${v_range##*.} # chomp everything up to the right-most matching "."
The repeated %% and ## basically mean you will get a "greedy" match, so you can say "1..4" or "1....5"; it doesn't matter how many repeats you have of the range delimiter. Of course, you can choose other delimiters such as a hyphen, as in "5-10", if you wish.
Now that you have extracted the start and end indices, you can then loop or whatever to your hearts content:
for ((a=v_start; a <= v_end ; a++))
do
echo "Looping with a=$a"
done
For more information on variable expansion, see 9.3 in the Advanced Bash Scripting Guide.
Postscript 5-Feb-2008:
We live and learn! Hat tip to buford for alerting me to the seq utility, which simplifies the iteration over a range, as in:
for a in `seq 1 10`
do
echo "Looping with a=$a"
done
You still need to determine the start and end values of the range, which is the whole point of the variable expansions approach posted here.
9 comments:
for f in `seq 1 10`; do echo $f; done
It's not a builtin, it's a program:
type seq:
seq is hashed (/usr/bin/seq)
It's part of coreutils.
$(jot - 1 16 2)
can be a replacement of the following two:
for((i=1;i<=16;i+=2))
$(seq 1 2 16)
** jot prints sequential or random
data
More of jot : http://unstableme.blogspot.com/2007/12/jot-print-sequential-or-random-data.html
// Jadu
Thanks Jadu, jot is yet another little utility I'd never heard of before!
Like your blog too..
for x in {1..4}; do echo $x; done
@anonymous:
for x in {1..4}; do echo $x; done
.. works OK with literals, but how do you substitute the range with a variable?
e.g.
v_range=1..4
for x in {${v_range}}; do echo $x; done
# doesn't work, nor does:
v_start=1
v_end=4
for x in {${v_start}..${v_end}}; do echo $x; done
# nor does:
for x in {v_start..v_end}; do echo $x; done
a=1; b=10; for i in `seq $a $b`; do echo $i; done
works for me
$a=1
$b=10
for i in 'seq $a $b`;do echo $i; done
Works for me.
@Szilard good thought, although I think it still requires some parsing in order to deal with parameters supplied like "1..4" or "1-3", which was the original problem I was facing
Post a Comment