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.
Related
We have a text file with 4 lines and a different number of words and i want to count the words per line and see if the number is even or odd but the result keeps saying
./oddwords.sh: line 14: syntax error near unexpected token `then'
./oddwords.sh: line 14: ` if[ n % 2 == 0 ]; then'
This is what ive done so far
#!/bin/bash
if [ $# -ne 1 ] ; then
{
echo "Wrong number of arguments!"
exit 1
}
fi
while read line ; do
n= echo "$(echo $line | wc -w)"
if[ n % 2 == 0 ]; then
echo "Is even"
else
echo "Is odd"
fi
done < $1
Using double brackets like
if [[ n % 2 == 0 ]]; then
and making the numbers variables at the top instead of just saying 2
a=2
b=1
at the beginning then referencing them later in the if statement like
if [[ $a%2 == 0 ]]; then
if you still have issues try
if [[ $a%2 -eq 0 ]]; then
Here are a couple sites i find useful for checking bash when I get stuck on something as well.
https://www.shellcheck.net/
https://explainshell.com/
I am getting an error which is:
exam.sh: line 5: conditional binary operator expected
exam.sh: line 5: syntax error near `%'
exam.sh: line 5: `if [[ $i % 2 = 0 ]]'
Here is my program code:
#!/bin/bash
i=1;
for user in "$#"
do
if [[ $i % 2 = 0 ]]
then
cd even
mkdir $user
.
else if [[ $i % 3 = 0 ]]
then
cd three
mkdir $user
.
else
cd other
mkdir $user
fi
fi
i=$((i + 1));
done
[[ doesn't do arithmetics. You need (( for that.
if (( i % 2 == 0 ))
Another option is to use $((...)) to generate a C-style
"boolean" that you can test explicitly.
if [ "$(( x % 2 == 0 ))" = 1 ]; then
echo "$x is even"
fi
This is objectively worse than if (( x % 2 == 0 )) in bash, but is useful if you need strict POSIX compliance.
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
what's wrong with my code? I am trying to print prime numbers upto n digits
echo Enter Number
read num
for (( i=2; $i <= $num ; i++ ))
do
c=0
for (( j=2; $j <= $i ; j++))
do
mod=$(($i % $j))
if [ "$mod" -eq 0 ]
then
c=`expr $c+1`
fi
done
if [ "$c" -eq 1 ]
then
echo $c
fi
done
I don't have any idea what I'm doing wrong. If someone could tell me how to fix it I would be thankful
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
newprime.sh: line 14: [: 0+1+1+1: integer expression expected
newprime.sh: line 14: [: 0+1: integer expression expected
expr requires parameters to be passed as separate arguments. Quoting the POSIX standard for expr:
The application shall ensure that each of the expression operator symbols [...] and the symbols integer and string in the table are provided as separate arguments to expr.
The code here is appending all the operators into a single argument, hence your problem.
Thus:
c=$(expr "$c" + 1)
...NOT...
c=$(expr $c+1)
But don't do that at all. It's more efficient and more readable to write:
c=$(( c + 1 ))
Optimized with less iterations POSIX shell version:
#!/usr/bin/env sh
printf %s 'Enter Number: '
read -r num
i=1
while [ "$i" -le "$num" ]; do
c=0
j=2
# Stop checking division when divisor power 2 is greater than number
# or we identifed a divisor
while [ "$((j * j))" -le "$i" ] && [ "$c" -eq 0 ]; do
c=$((i % j == 0))
j=$((j + 1))
done
if [ "$c" -eq 0 ]; then
printf '%s\n' "$i"
fi
i=$((i + 2))
done
Or using a function:
#!/usr/bin/env sh
is_prime() {
j=2
# Check j is a divisor of argument number, while j^2 is less than number
while [ "$((j * j))" -le "$1" ]; do
# If j is a divisor of number before the end of the loop
# number is not prime, so return 1
[ "$(($1 % j))" -eq 0 ] && return 1
j=$((j + 1))
done
}
printf %s 'Enter Number: '
read -r num
i=1
while [ "$i" -le "$num" ]; do
if is_prime "$i"; then
printf '%s\n' "$i"
fi
i=$((i + 2))
done
Don't use expr. Put your mathematical expression inside (( )) (or echo $(( )) to print the result), and the shell will evaluate it.
See what the expr output looks like, vs regular shell arithmetic:
$ expr 0+1
0+1
$ echo "$((0+1))"
1
-eq with test, or single square brackets (eg [ 1 -eq 2 ]) prints an error if both operands aren't integers. That's what's causing your error.
Here's a fast and concise way to list primes in bash. You can put it in a function or script:
for ((i=2; i<="${1:?Maximum required}"; i++)); do
for ((j=2; j<i; j++)); do
((i%j)) || continue 2
done
echo "$i"
done
edit: Just to explain something, if (([expression])) evaluates to 0, it returns non-zero (1) (failure). If it evaluates to any other number (positive or negative), it returns zero (true). When a number divides evenly in to i, the modulo (%) (remainder) is zero. Hence the command fails, we know it's not prime, and we can continue the outer loop, for the next number.
I've seen other answers about bash integer checks and comparisons, however the results I'm getting are very confusing to me.
Suppose I have this script:
if [[ $1 -eq $1 ]] ;then
echo "number"
else
echo "not number"
fi
if (( $1 >= 0 )) ;then
echo "number"
else
echo "not number"
fi
If I pass a string for parameter one , I get back "number".
That's because string is understood as a variable whose value is 0, and 0 >= 0 is true. Try with > (but it will report 0 as not number - but it already misclassifies all negative integers).
Cf:
a=1
b=a
x=b
(( x > 0 )) && echo 1
a=0
(( x > 0 )) || echo 0
or even
$ a=x
$ x=a
$ (( x > 0 ))
bash: ((: a: expression recursion level exceeded (error token is "a")
Bash tries hard to resolve the variable:
(
for l in a{1..1023} ; do
printf "$l\n$l="
done
echo 1
echo '((a1>0))'
) | tail -n+2 | bash