For loop running only once in Bash [duplicate] - bash

This question already has answers here:
Brace expansion with variable? [duplicate]
(6 answers)
Closed 7 years ago.
I've just started shell scripting.
Here is my code:
read totalNumbers
for i in {1..$totalNumbers..1}
do
echo "Welcome $i times"
done
When the input is given as 100, I'm getting the output as
Welcome {1..100..1} times
But I need something like
Welcome 1 times
Welcome 2 times
Welcome 3 times
.
.
.
Welcome 100 times

You cannot use variable names inside {..} in shell.
You can use ((..)) for arithmetic in BASH:
for (( i=1; i <= $totalNumbers; i++ )); do
echo "Welcome $i times"
done
Even for (( i=1; i <= totalNumbers; i++ )) would work.

If you want to use
{1..$totalNumbers..1}
anyway, replace it by
$(eval echo {1..$totalNumbers..1})
$(...) runs a subshell.

Related

Bash script for loop which the last statement is first calculated [duplicate]

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

For loop over sequence of large numbers in Bash [duplicate]

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

Brace expansion of {1..$n} [duplicate]

This question already has answers here:
Brace expansion with a Bash variable - {0..$foo}
(5 answers)
Closed 4 years ago.
I am trying to loop from 1 to n where n is from user input.
If I do:
read n
echo {1..$n}
I get this output for the input 5
{1..5}
How do I make it expand to
1 2 3 4 5
Keep it simple by trying to do it with a for loop as follows.
echo "enter number..."
read n
for((i=1;i<=n;i++)); do
echo "$i"
done
Or use seq with for loop as follows too.
echo "Enter number:"
read howmany
for i in $(seq 1 $howmany); do
echo "$i";
done
Curly braces don't support variables in bash, though eval could be used but it is evil and have loopholes, why so see this link carefully http://mywiki.wooledge.org/BashFAQ/048

Calculating a loop size in bash script gives back different output than writing the size hard coded [duplicate]

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

how to set variable for bash loop array [duplicate]

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

Resources