For loop range in Bash [duplicate] - bash

This question already has answers here:
Sequences expansion and variable in bash [duplicate]
(7 answers)
Closed 7 years ago.
Im trying a code in bash to generate prime nos as follows:
#!/bin/bash
echo "Enter till where u wish to generate"
read num
echo "Generating prime numbers from 2 to $num"
flag="prime"
for i in {2..$num}
do
for j in {2..$((${num}-1))}
do
[ $((${i}%${j})) -eq 0 ] && flag="nprime" || flag="prime"
break
done
[ "$flag" == "prime" ] && echo "$i"
done
Upon execution, it throws an error because the for loop takes the sequence mentioned in the curly braces as it is not as a sequence.
Could you guide me as to where am i going wrong ?

man bash in my version says:
A sequence expression takes the form {x..y[..incr]}, where x and y are either integers or single characters, and incr, an optional increment, is an integer.
You can't use variables in ranges. Try seq instead:
for i in $(seq 2 $num) ; do
Note that incr for seq goes between x and y.

Use:
for ((i=2; i<=$num; i++))

Related

How do I write a Bash script for a C program that takes 4 numerical inputs? [duplicate]

This question already has answers here:
How to zero pad a sequence of integers in bash so that all have the same width?
(15 answers)
Closed 2 years ago.
I am writing a bash script for a c program, where the program asks for a 4 numerical pin inputs. However, when I wrote the script, the output seems to run in a loop, but it doesn't break where it gets identified as the correct number the program will accept.
#!/bin/bash
RANGE=9000
count=${RANDOM:0:4}
while [[ "$count" -le $RANGE ]]
do
number=$RANDOM
(( "number %= $RANGE" ))
echo $number
if [[ "$count" == "$RANGE" ]]; then
break
fi
done
When I run it, I can see some numbers in the output that returned as 2 or 3 digits, instead of 4. So in theory, what I want to do is find a random number that is 4 digits that the program will take, but I don't know what is the random number, so essentially it is a brute force, or just me manually guessing the pin number.
If all you need is a random 4-digit number, you can do that with:
printf -v number "%04d" $((RANDOM % 10000))
The $RANDOM gives you a random number 0..32767, the % 10000 translates that to the range 0..9999 (not perfectly distributed, but should be good enough for most purposes), and the printf ensures leading zeros are attached to it (so you'll see 0042 rather than 42, for example).
You can test it with the following script:
(( total = 0 ))
(( bad = 0 ))
for i in {1..10000} ; do
printf -v x "%04d" $((RANDOM % 10000))
(( total += 1 ))
[[ "${x}" =~ ^[0-9]{4}$ ]] || { echo Bad ${x}; (( bad += 1 )); }
done
(( good = total - bad ))
echo "Tested: ${total}, bad ${bad}, good ${good}"
which should give you:
Tested: 10000, bad 0, good 10000

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

if else dividing in BASH [duplicate]

This question already has answers here:
Arithmetic expressions in Bash?
(5 answers)
Closed 6 years ago.
I am doing a school assignment in bash and got this code:
if a < 0
a = a/b
else
a = b/a
fi
The assignment says that we need to divide two number read from the keyboard, and check if the first number is larger than the number 0.
echo "Write two numbers, with a space, that need to be divided:"
read a b
if a > 0
a = $a / $b
else
a = $b / $a
fi
echo "$a"
What am I doing wrong here?
Creating a math context in bash uses (( )). Note that bash only supports integer math natively -- be sure you aren't expecting fractional output (or using fractional inputs), and see BashFAQ #22 if this limitation is relevant to you.
if (( a > 0 )); then
a=$(( a / b ))
else
a=$(( b / a ))
fi

input vs variable comparison isn't working? [duplicate]

This question already has answers here:
How do I compare two string variables in an 'if' statement in Bash? [duplicate]
(12 answers)
Closed 6 years ago.
Here is a random number generator followed by a line clear timer and you are then to try and input the number that you saw. I cant seem to set up the comparison between the randNum variable and the input. I tried setting a defined value for the input as well and still receive an error "command not found" when checking input vs randNum variable
n=$RANDOM$RANDOM$RANDOM; let "n %= 10000000000";
echo $n
for i in {5..1}; do echo $i; sleep 1; tput cuu1; tput el; done
tput cuu1; tput el
echo "what was that number?"
#read input
input=999999999
if [$input == $n]
then
echo "you are correct"
else
echo "you are incorrect"
fi
Shells need spaces around brackets [ and ] when used for this purpose (replacement syntax for the test command), and you should better use -eq instead of == for numeric comparison:
if [ $input -eq $n ]
If you use the arithmetic comparison, rather than the old testcommand (a.k.a. [) then you can avoid these issues. Spaces here are less important inside the brackets:
if (( input == n ))
Note that the leading $ is not required (and using it can cause issues)

Resources