whats wrong with this while loop in unix - shell

I am a newbie .Please help me with this
The output says syntax error near unexpected token 'do'
The code is
if [ $# -eq 0 ];
then
echo "Command line arguments are missing."
else
n=$1
sum=0
while[ $n -gt 0 ]
do
rem=$(( $n % 10 ))
sum=$(( $sum + $rem ))
n=$(( $n / 10 ))
done
echo "Sum of digit for given number is $sum "
fi

A whitespace after while. Try this out:
if [ $# -eq 0 ];
then
echo Command line arguments are missing.
else
n=$1
sum=0
while [ $n -gt 0 ];
do
rem=$(( $n % 10 ))
sum=$(( $sum + $rem ))
n=$(( $n / 10 ))
done
echo "Sum of digit for given number is $sum"
fi

Put spaces before and after [ and ].
You can replace the while-loop with
sum=$(( $(echo $1| sed 's/./&+/g; s/+$//' ) ))

Related

Error getting in the second if statement in bash script

n=20
x=3
count=0
flag=0
i=1
declare -a arr[n+1]
for (( j=0;j<=n;j++ ))
do
arr+=(0)
done
#echo "${arr[#]}"
while [[ $count -ne $n ]]
do
if [[ $i -le $n ]]
then
if [[ ${arr[$i]} -eq '0' ]]
then
echo "Value is ${arr[$i]}"
#${arr[$(i-1)]}= (( ${arr[$i-1]++} ))
${arr[$i]}+=${arr[$i]}
echo " "
#echo -n "${arr[$i]}"
echo -n " $i"
count=$(( count+1 ))
i=$(( i+1+x ))
else
i=$(( i+1 ))
fi
else
i=$(( i-n ))
flag=$(( flag+1 ))
fi
done
echo " "
echo "No of round : $flag"
This is the whole code, I've tried to print numbers that follows this: n=20 is the number of elements and x=3 is the number that we have to avoid. For example,
20
3
1,5,9,13,17,2,6,10,14,18,3,7,11,15,19,4,8,12,16,20,
3
But, the problem is that my second if condition is not fulfilling, if ignores the condition. Above example is for the C++, but in bash script, 2nd if statement isn't working. This can be because syntax is wrong. So can you please help me to find the mistakes.
Output of the above code:
output
${arr[$i]}+=${arr[$i]}
This is incorrect. $ should not be used when you assign the value.
If you want to double the value, replace this string with the following:
arr[$i]=$(( ${arr[$i]} + ${arr[$i]} ))
Or what you want to do there?

Values of an array not comparing to numbers correctly

Im trying to get an array from grades.txt, and determine what letter grade it should be assigned.
I either get
hw4part2.sh: line 26: [: : integer expression expected
If i use -ge or
hw4part2.sh: line 26: [: : unary operator expected
If i use >=
Below is the code im trying to get working
mapfile -t scores < grades.txt
numOScores=0
numOA=0
numOB=0
numOC=0
numOD=0
numOF=0
DoneWScores=0
A=90
B=80
C=70
D=60
F=59
while [ $DoneWScores -eq 0 ]
do
numOScores=$((numOScores + 1))
if [ "${scores[$numOScores]}" -ge "$A" ]
then
echo "A"
elif [ "${scores[$numOScores]}" -ge "$B" ]
then
echo "B"
elif [ "${scores[$numOScores]}" -ge "$C" ]
then
echo "C"
elif [ "${scores[$numOScores]}" -ge "$D" ]
then
echo "D"
elif [ "${scores[$numOScores]}" -le "$F" ]
then
echo "F"
else
echo "Done/error"
DoneWScores=1
fi
done
If anyone knows what my problem is, that'd be greatly appreciated
Consider this:
#!/usr/bin/env bash
if (( ${BASH_VERSINFO[0]} < 4 )); then
echo "Bash version 4+ is required. This is $BASH_VERSION" >&2
exit 1
fi
letterGrade() {
if (( $1 >= 90 )); then echo A
elif (( $1 >= 80 )); then echo B
elif (( $1 >= 70 )); then echo C
elif (( $1 >= 60 )); then echo D
else echo F
fi
}
declare -A num
while read -r score; do
if [[ $score == +([[:digit:]]) ]]; then
grade=$(letterGrade "$score")
(( num[$grade]++ ))
echo "$grade"
else
printf "invalid score: %q\n" "$score"
fi
done < grades.txt
for grade in "${!num[#]}"; do
echo "$grade: ${num[$grade]}"
done | sort

What is need of Count in the following bash script?

echo 'Enter no'
read x
n=2
while [ $n -le $x ]
do
i=2
count=1
while [ $i -lt $n ]
do
if [ `expr $n % $i` -eq 0 ]
then
count=0
break
fi
i=`expr $i + 1`
done
if [ $count -eq 1 ]
then
echo "$n is Prime"
fi
n=`expr $n + 1`
done
It is not really a counter, just a flag.
If any modulus operation returned a 0, then the value is not prime. The flag is set so that after the inner loop completes, you can see that the value was not prime.
If the value never was divisible, then the counter flag was never reset to 0, so you know it is prime.

how to extract numbers from this echo into separate variables?

Sorry about bits and snippit of information
So I am writing an average shell script program
so if use inputs
echo 1 3, .... | sh get_number
I would have to pull the numbers seperated by spaces from echo to be
var1 = 1, var2= 3, etc.
I tried
#!/bin/sh
sum=0
for i in $*
do
sum=`expr $sum + $i`
done
avg=`expr $sum / $n`
echo Average=$avg
but doesnt work....
do I include a read here?
also how would I do
sh get_number <file1>, <file2>... to grab numbers in them and sum them
in shell script?
Thanks
Sounds like you are looking for the read shell builtin:
% echo "1 2 3 4" | read a b stuff
% echo $b
2
% echo $stuff
3 4
To fix up your code:
for i in $*; do
sum=$(( sum + i ))
n=$(( n + 1 ))
done
echo "Average=$(( sum / n ))"
#!/bin/sh
while [ $# -gt 0 ]; do
(( i++ ))
(( sum += $1 ))
shift
done
echo "Average=$(( sum/i ))"
Note: This fails in dash which is the closest shell I could find to a real sh.
An example of reading values from files passed as command line arguments or from lines read from stdin:
add_to_sum() {
set $*
while [ $# -gt 0 ]; do
I=`expr $I + 1`
SUM=`expr $SUM + $1`
shift
done
}
I=0
SUM=0
if [ $# -gt 0 ]; then
# process any arguments on the command line
while [ $# -gt 0 ]; do
FILE=$1
shift
while read LINE; do
add_to_sum "$LINE"
done < "$FILE"
done
else
# if no arguments on the command line, read from stdin
while read LINE; do
add_to_sum "$LINE"
done
fi
# be sure not to divide by zero
[ $I -gt 0 ] && echo Average=`expr $SUM / $I`

How to write a condition in bash

check even number - OK
if [ $(( $n % 2 )) -eq 0 ]
then
echo "$n is even number"
fi
how to check odd number ?
if [ $(( $n % ????? )) -eq 0 ]
then
echo "$n is odd number"
fi
Thank
Use "not equal 0":
if [ $(( $n % 2)) -ne 0 ]
then
echo "$n is odd"
fi
See also: http://tldp.org/LDP/abs/html/comparison-ops.html
You can also use "n%2 equals 1" since the remainder of an odd number divided by two is one:
if [ $(( $1 % 2)) -eq 1 ]
then
echo "$1 is odd"
fi
But the former (not equal 0) is the more general case, so I would prefer it.
All the answers above use a single square bracket [ which is outdated in bash (we're talking about bash, right?). The best practice to achieve the determination of an odd or even number n is:
if (( n%2==0 )); then
printf "%d is even\n" $n
else
printf "%d is odd\n" $n
fi
or, as the OP wants it, i.e., check if n is odd:
if (( n%2 )); then
printf "%d is odd\n" $n
fi
echo -n "Enter numnber : "
read n
rem=$(( $n % 2 ))
if [ $rem -eq 0 ]then
echo "$n is even number"
else
echo "$n is odd number"
fi
I prefer the simplicity of:
x=8; ((x%2)) || echo even
x=7; ((x%2)) && echo odd

Resources