Loop condition in bash - bash

In bash script, below while loop is supposed to print 1 to 4 number.
But this one is resulting as an infinite loop.
COUNT=1
while [ $COUNT < 5 ];
do
echo $COUNT
COUNT=$(($COUNT+1))
done
Is there any fault in condition or syntax ? (I think so...)

Use -lt instead of <:
COUNT=1; while [ $COUNT -lt 5 ]; do echo $COUNT; COUNT=$(($COUNT+1)); done
1
2
3
4
BASH syntax with [ doesn't recognize >, <, <=, >= etc operators. Check man test.
Even better is to use arithmetic processing in (( and )):
COUNT=1; while (( COUNT < 5 )); do echo $COUNT; ((COUNT++)); done
OR using for loop:
for (( COUNT=1; COUNT<5; COUNT++ )); do echo $COUNT; done

Related

How to say less than but no equal to in bash?

I'm getting an error with this, I did my research but found nothing.
if [ $value -lt 3 -ne 1 ]; then
execute code
fi
line 6: [: syntax error: -ne unexpected
One way to make this work is
if [ "${value}" -lt 3 ] && [ "${value}" -ne 1 ]; then
echo "Hello"
fi
I like to switch to arithmetic expressions using (( when I need tests like these:
declare -a values=(1 2 3)
for value in "${values[#]}"; do
if (( value != 1 && value < 3 )); then
echo "execute code for $value"
fi
done
The above outputs:
execute code for 2
use (( )) brackets for arithmetic operations and [[ ]] for strings comparison
$ is redundant in round brackets so (( $a == 1 )) is the same as (( a == 1 ))
typeset a=2
(( a < 3 )) && (( a != 1 )) && echo "Execute code"
more details : http://faculty.salina.k-state.edu/tim/unix_sg/bash/math.html

How to process value from for loop in shell

I have to a perform logic like this.
I have a array.
expression for this in shell
[(first no + arrlen) - ( index +1 ) - ge 10 ]
I have code this like this but it's not working
#!/bin/bash
array=(4 5 6 7 8 9)
for i in ${array[#]}
do
echo $i
done
echo "${#array[#]}"
l=${#array[#]}
count=0
for (( i=0; i < ${#array[#]}; i++ ))
do
if [ ($(`expr $i + $l`) - $(`expr ${!array[#]} + 1`)) -ge 10 ]
then
count=`expr $count + 1`
else
echo
fi
done
Your code could look like this:
#!/bin/bash
array=(4 5 6 7 8 9)
for i in "${array[#]}"; do
echo "$i"
done
length=${#array[#]}
first=${array[0]}
count=0
for (( i=0; i < length; i++ )); do
if (( (first + length) - (i + 1) >= 10 )); then
((count++))
else
echo "something"
fi
done
Don't use expr, use (( )) for arithmetic expressions
Quote expansions: "$i", "${array[#]}", ...
${!array[#]} expands to ALL indexes of your array, not the current index

While loop creating multiply variables with counter

#!/bin/bash
n=1
while (( $n <= 5 ))
do
num$n=`echo "$n"`
n=$(( n+1 ))
done
echo "$num1"
ok so what I am trying to do is create a while loop that will create variables and just put something into it in this case its just the value of n but i cant get it to do this!
so basically it will create num1, num2, num3 and so on
echo "$num1"
echo "$num2"
echo "$num3"
should display
1
2
3
but i keep getting an error am i missing something here cause it shouldnt be anything crazy to do this...
Try with
#!/bin/bash
n=1
while (( $n <= 5 ))
do
eval num$n=`echo "$n"`
n=$(( n+1 ))
done
echo "$num1"
echo "$num2"
echo "$num3"
The problem here is that bash is trying to evaluate num$n as a command, which does not exist, so the error.
Don't dynamically create numbered variable names like this; use an array.
n=1
while (( $n <= 5 )); do
nums[$n]=$n # No need to execute $(echo ...)
n=$((n+1))
done
echo "${num[1]}"
echo "${num[2]}"
echo "${num[3]}"

One line if statement in bash

I've never programed in bash... yet I'm trying to solve a problem for an anchievement in a game (codingame.com)
I have the following code:
for (( i=0; i<N-1; i++ )); do
tmp=$(( sorted_array[i+1] - sorted_array[i] ));
if [ $tmp < $result ]; then result=$tmp fi
done
And this error:
/tmp/Answer.sh: line 42: syntax error near unexpected token `done'at Answer.sh. on line 42
/tmp/Answer.sh: line 42: `done' at Answer.sh. on line 42
I want to compare adjacent values of my array and store the minimun diference between them... but I cant figure how to do an If statement in bash
Each command must be properly terminated, either by a newline or a semi-colon. In this case, you need to separate the assignment of result from the keyword fi. Try adding a semi-colon;
for (( i=0; i<N-1; i++ )); do
tmp=$(( sorted_array[i+1] - sorted_array[i] ))
if [ "$tmp" -lt "$result" ]; then result=$tmp; fi
done
Also, you need to use lt rather than <, since < is a redirection operator. (Unless you intend to run a command named $tmp with input from a file named by the variable $result)
You are missing a semicolon and need to use -lt instead of <, as others pointed out.
An alternative to the if statement would be to use the logical and operator &&:
for (( i=0; i<N-1; i++ )); do
tmp=$(( sorted_array[i+1] - sorted_array[i] ))
[ $tmp -lt $result ] && result=$tmp
done
Your if needs to be followed by a fi command, but you don't have any such command. You have a fi in your code, but it's in the middle of another command, so it no more completes the if then the fi in echo fi would. If you're going to merge lines together, you need to use a semi-colon to separate the commands.
So to collapse
for (( i=0; i<N-1; i++ ))
do
tmp=$(( sorted_array[i+1] - sorted_array[i] ))
if [ $tmp -lt $result ]
then
result=$tmp
fi
done
you'd use
for (( i=0; i<N-1; i++ )); do
tmp=$(( sorted_array[i+1] - sorted_array[i] ))
if [ $tmp -lt $result ]; then result=$tmp; fi
done
Exception: do and then can be followed by a command, so you don't need a semi-colon after them when you merge in the next line.
Notice how you don't need to terminate your commands with ;? ; is only needed between commands.
Inside of a test ([]), -lt is used to compare numbers.

Syntax error near unexpected token `if' in shell scripting

I was trying a sample program, to check the odd and even no's and was getting an error as below,
#!/bin/bash
N=10
for i in 1..N
if [$i/2 == 0]
then
echo "even"
else
echo "Odd"
fi
Error:
./case.sh: line 5: syntax error near unexpected token `if'
./case.sh: line 5: `if [$i/2 == 0]'
EDITED :
#!/bin/bash
N=10
for i in 1..N
do
if(( ($i/2) == 0 ));
then
echo "even"
else
echo "Odd"
fi
done
error :
./case.sh: line 6: ((: (1..N/2) == 0 : syntax error: invalid arithmetic operator (error token is "..N/2) == 0 ")
Odd
Correct working code :
#!/bin/bash
N=3
for (( i=1; i <= N; i++ ));
#for i in 1..N; // This didnt work
do
if [[ $i/2 -eq 0 ]]
#if (( i/2 == 0 )); // This also worked
then
echo "even"
else
echo "Odd"
fi
done
[ ] or [[ ]] needs spaces between its arguments. And in your case you should use [[ ]] or (( )) as [ ] can't handle division along with comparison:
if [[ 'i / 2' -eq 0 ]]; then
if (( (i / 2) == 0 )); then
for i in 1..N; do should also be
for (( i = 1; i <= N; ++i )); do
You probably meant to have a form of brace expansion, but you can't apply a parameter name on it:
{1..10} ## This will work.
{1..N} ## This will not work.
Using eval may fix it but better go for the other form of for loop instead.
Try this :
#!/bin/bash
N=10
for i in $(seq 1 $N); do
if [ `expr $i % 2` -eq 0 ]
then
echo "even"
else
echo "Odd"
fi
done
1..N is not a valid syntax in bash(though I think you might be coming from ruby background), you can use seq.

Resources