This question already has answers here:
Is it possible to use a variable in for syntax in bash?
(3 answers)
Closed 8 years ago.
I would like to have a bash loop function like below, with decreasing sequency:
for i in {8..2}
do
...
done
And the 8 and 2 can be set as a variable, like:
start=$1
end=$2
for i in {$start..$end}
do
...
done
But seem this dose not work. How can I do this?
Thanks for all the quick answers, later I found the answer here.
descending loop with variable bash
solution:
start=$1
end=$2
for i in `seq $start -1 $end`
do
...
done
Thanks~
$ start=8; end=2; for ((i = start; i >= end; i--)); do echo "${i}"; done
8
7
6
5
4
3
2
Nope. But here is a workaround
start=$1
end=$2
for i in $(seq $start $end)
do
...
done
You can't use variable substitution there since the {n..m} is already one.
Try using seq:
for i in `seq $start $end`
do
...
done
Alternatively you could do a while loop incrementing the loop variable by manually:
i=$start
while [ $i -lt $end ]; do
...
: $[i++]
done
Although with while you have to be aware if $start is smaller or greater than $end
Related
This question already has answers here:
How do I iterate over a range of numbers defined by variables in Bash?
(20 answers)
Closed 3 years ago.
I wrote this bash script
x=64
y=1
ans=$((x-y))
z=`expr $ans`
for i in {1..$z}
do
echo $i
done
Actually, I would like to print i values from 1 to 63, 63 which is first
obtained from the above addition. But it just prints {1..63}
Can someone please help me. Thanks in advance.
You're best of using a C-style for loop:
for ((n=$y; n<$x; n++)); do
echo $n
done
using seq :
for i in $(seq 1 $z)
do
echo $i
done
This question already has answers here:
Bash command line and input limit
(4 answers)
Closed 4 years ago.
In a Bash script I am using a simple for loop, that looks like:
for i in $(seq 1 1 500); do
echo $i
done
This for loop works fine. However, when I would like to use a sequence of larger numbers (e.g. 10^8 to 10^12), the loop won't seem to start.
for i in $(seq 100000000 1 1000000000000); do
echo $i
done
I cannot imagine, that these numbers are too large to handle. So my question: am I mistaken? Or might there be another problem?
The problem is that $(seq ...) is expanded into a list of words before the loop is executed. So your initial command is something like:
for i in 100000000 100000001 100000002 # all the way up to 1000000000000!
The result is much too long, which is what causes the error.
One possible solution would be to use a different style of loop:
for (( i = 100000000; i <= 1000000000000; i++ )) do
echo "$i"
done
This "C-style" construct uses a termination condition, rather than iterating over a literal list of words.
Portable style, for POSIX shells:
i=100000000
while [ $i -le 1000000000000 ]; do
echo "$i"
i=$(( i + 1 ))
done
This question already has answers here:
How do I iterate over a range of numbers defined by variables in Bash?
(20 answers)
Closed 5 years ago.
Is it possible to do something like this:
start=1
end=10
echo {$start..$end}
# Ouput: {1..10}
# Expected: 1 2 3 ... 10 (echo {1..10})
In bash, brace expansion happens before variable expansion, so this is not directly possible.
Instead, use an arithmetic for loop:
start=1
end=10
for ((i=start; i<=end; i++))
do
echo "i: $i"
done
OUTPUT
i: 1
i: 2
i: 3
i: 4
i: 5
i: 6
i: 7
i: 8
i: 9
i: 10
You should consider using seq(1). You can also use eval:
eval echo {$start..$end}
And here is seq
seq -s' ' $start $end
You have to use eval:
eval echo {$start..$end}
If you don't have seq, you might want to stick with a plain for loop
for (( i=start; i<=end; i++ )); do printf "%d " $i; done; echo ""
I normally just do this:
echo `seq $start $end`
Are you positive it has be BASH? ZSH handles this the way you want. This won't work in BASH because brace expansion happens before any other expansion type, such as variable expansion. So you will need to use an alternative method.
Any particular reason you need to combine brace and variable expansion? Perhaps a different approach to your problem will obviate the need for this.
use -s
ex:
seq -s ' ' 1 10
output: 1 2 3 4 5 6 7 8 9 10
This question already has answers here:
Read file for value, loop until value = $foo?
(3 answers)
Closed 5 years ago.
#!/bin/bash
i=1
cat days.txt | while read days
do
echo $i $days
let i++
done
I want to change while loop into until loop
#!/bin/bash
i=1
until conditions
do
echo $i $days
let i++
done
expected result
Monday
Tuesday
Wednesday
Blah Blah Blah
while read can be written more awkwardly as until ! read:
i=1
until ! read -r days; do
echo "$i $days"
i=$(( i + 1 ))
done < file
while command does something as long as command exits successfully, whereas until command does something until command exits unsuccessfully. The ! is used to negate the exit code of read.
I wonder If it is possible to write "for i in {n..k}" loop with a variable.
For example;
for i in {1..5}; do
echo $i
done
This outputs
1
2
3
4
5
On the other hands
var=5
for i in {1..$var}; do
echo $i
done
prints
{1..5}
How can I make second code run as same as first one?
p.s. I know there is lots of way to create a loop by using a variable but I wanted to ask specifically about this syntax.
It is not possible to use variables in the {N..M} syntax. Instead, what you can do is use seq:
$ var=5
$ for i in $(seq 1 $var) ; do echo "$i"; done
1
2
3
4
5
Or...
$ start=3
$ end=8
$ for i in $(seq $start $end) ; do echo $i; done
3
4
5
6
7
8
While seq is fine, it can cause problems if the value of $var is very large, as the entire list of values needs to be generated, which can cause problems if the resulting command line is too long. bash also has a C-style for loop which doesn't explicitly generate the list:
for ((i=1; i<=$var; i++)); do
echo "$i"
done
(This applies to constant sequences as well, since {1..10000000} would also generate a very large list which could overflow the command line.)
You can use eval for this:
$ num=5
$ for i in $(eval echo {1..$num}); do echo $i; done
1
2
3
4
5
Please read drawbacks of eval before using.