While loop with a certain amount of loops - unix

repeat=0
echo "Please enter a number dividable by 5"
read input
loop= `expr $input / 5`
while [ $repeat -ne $loop ]
do
echo "repeat"
repeat= `expr $repeat + 1`
done
For this code, so if i enter 15, the code will repeat 3 times, it will echo 3 times of repeat, but from now i keep getting command not find from "repeat =expr $repeat + 1. not sure what is happening.

Spacing is important in bash. You need to remove the space after the =. i.e.
loop=`expr $input / 5`
and
repeat=`expr $repeat = 1`
With that space in place, it is trying to execute the result of the expr call, and complaining because there is no command called 3

You can't have a space after the = sign in setting the loop and repeat variable

Related

Define specific output count in EXPR command

I have a scenario wherein I want to have 9 character count in expr.
I have sample code which is:
var1=012345678 #this is 9 characters
sum=`expr $var1 + 1`
echo "$sum"
Here is the result:
./sample.sh : 12345679 #this is only 8 characters
My expected output:
./sample.sh : 012345679
Any help on this?
The leading zero is removed when doing the math.
You can force a 9 length output using printf "%09d" 123.
When you try to use the the syntax ((sum=${var1} + 1 )) you have another problem: When the first digit is 0, bash expects a different radix.
You can remove the first 0 with
var1=012345678
echo "${var1#0}"
This only helps with your input, not with 00012.
Removing the leading zeroes and printing the sum can be done with echo $((10#$var1))
var1=00012345678
((sum=$((10#$var1)) + 1))
printf "%09d\n" $sum
This can be solved easier with
var1=00012345678
echo "${var1} 1" |awk '{ printf("%09d\n", $1 + $2) }'
You can avoid the echo with
awk -v var1=$var1 'BEGIN { printf("%09d\n", var1 + 1) }'
The BEGIN is used for parsing without an inputfile.
The option -v is a clean way to use a shell variable inside an awk script.
Do not try things with quotes, one day it will shoot your own foot:
# Don't do this
awk 'BEGIN { printf("%09d\n", '${var1}' + 1) }' # Just do not do it

Appending whitespace to a variable in AWK script

I have an AWK script, which receives an input variable from another script.
The length of the input variable is compared. if the length is 3, two whitespace is added infront of variable. If the length is 4, 1 whitespace is added in front. I could compare the length but am not able to append white space.
I tried the following in AWK script
if (length(input_variable) ==3 ) {
input_variable = " "input_variable
} else if(length(input_variable) ==4 ){
input_variable = " "input_variable
}print input_variable
Output: No value is getting printed. Please help me
you should use printf
awk '{printf "%5s", $1}'
pads with spaces on the left to the desired length, don't reinvent.

bc arithmetic Error

i am trying to solve this bash script which reads an arithmetic expression from user and echoes it to the output screen with round up of 3 decimal places in the end.
sample input
5+50*3/20 + (19*2)/7
sample output
17.929
my code is
read x
echo "scale = 3; $x" | bc -l
when there is an input of
5+50*3/20 + (19*2)/7
**my output is **
17.928
which the machine wants it to be
17.929
and due to this i get the solution wrong. any idea ?
The key here is to be sure to use printf with the formatting spec of "%.3f" and printf will take care of doing the rounding as you wish, as long as "scale=4" for bc.
Here's a script that works:
echo -e "please enter math to calculate: \c"
read x
printf "%.3f\n" $(echo "scale=4;$x" | bc -l)
You can get an understanding of what is going on with the above solution, if you run this command at the commandline: echo "scale=4;5+50*3/20 + (19*2)/7" | bc the result will be 17.9285. When that result is provided to printf as an argument, the function takes into account the fourth decimal place and rounds up the value so that the formatted result displays with precisely three decimal places and with a value of 17.929.
Alternatively, this works, too without a pipe by redirecting the here document as input for bc, as follows which avoids creating a sub-shell:
echo -e "please enter math to calculate: \c"
read x
printf "%.3f\n" $(bc -l <<< "scale=4;$x")
You are not rounding the number, you are truncating it.
$ echo "5+50*3/20 + (19*2)/7" | bc -l
17.92857142857142857142
$ echo "scale = 3; 5+50*3/20 + (19*2)/7" | bc -l
17.928
The only way I know to round a number is using awk:
$ awk 'BEGIN { rounded = sprintf("%.3f", 5+50*3/20 + (19*2)/7); print rounded }'
17.929
So, in you example:
read x
awk 'BEGIN { rounded = sprintf("%.3f", $x; print rounded }'
I entirely agree with jherran that you are not rounding the number, you are truncating it. I would go on to say that scale is probably just not behaving at all the way you want it, possibly in a way that noone would want it to behave.
> x="5+50*3/20 + (19*2)/7"
> echo "$x" | bc -l
17.92857142857142857142
> echo "scale = 3; $x" | bc -l
17.928
Furthermore, because of the behaviour of scale, you are rounding each multiplication/division separately from the additions. Let me prove my point with some examples :
> echo "scale=0; 5/2" | bc -l
2
> echo "scale=0; 5/2 + 7/2" | bc -l
5
> echo "5/2 + 7/2" | bc -l
6.00000000000000000000
However scale without any operation doesn't work either. There is an ugly work-around :
> echo "scale=0; 5.5" | bc -l
5.5
> echo "scale=0; 5.5/1" | bc -l
5
So tow things come out of this.
If you want to use bc's scale, do it only for the final result already computed, and even then, beware.
Remember that rounding is the same as truncating a number + half of the desired precision.
Let us take the example of rounding to the nearest integer, if you add .5 to a number that should be rounded up, its integer part will take the next integer value and truncation will give the desired result. If that number should have been rounded down, then adding .5 will not change its integer value and truncation will yield the same result as when nothing was added.
Thus my solution follows :
> y=$(echo "$x" | bc -l)
> echo "scale=3; ($y+0.0005)/1" | bc -l # scale doesn't apply to the +, so we get the expected result
17.929
Again, note that the following doesn't work (as explained above), thus breaking it up in two operations is really needed :
> echo "scale=3; ($x+0.0005)/1" | bc -l
17.928

Assigning a value to a variable in a loop and printing it outside the loop using korn shell

I am having problem when trying to assign a value to a variable in a loop and trying to print it outside the loop using korn shell. I want to use that variable in later part of my script. So I am trying to test by printing the value of the dynamic variable. I just assigned to it from my array.
#!/usr/bin/ksh
clear
BINPATH=/usr/bin
SVR_LIST=servers_list
set -A SERVERS `cat $SVR_LIST`
typeset -i i=0
Sn=${#SERVERS[#]}
#echo "Number of servers in an array are .................." $Sn
while [ $i -lt ${#SERVERS[#]} ] ; do
#print ${SERVERS[$i]}
typeset -l s${i}=${SERVERS[$i]}
#eval echo "Value of Variable is" \${s$i}
#s=\${s$i}
(( i=i+1 ))
done
s=\${s$i}
eval echo "value of s is " $s
s=eval \${s0}
APPSERVER1=$s
echo $APPSERVER1
s=eval \${s1}
APPSERVER2=$s
echo $APPSERVER2
I am getting following error.
value of s is
./variableTest.sh[21]: ${s0}:not found
${s4}
./variableTest.sh[24]: ${s1}:not found
${s4}
here is working codeā€¦
#!/bin/ksh
clear
#BINPATH=/usr/bin
SVR_LIST=test
set -A SERVERS `cat $SVR_LIST`
typeset -i i=0
Sn=${#SERVERS[#]}
#echo "Number of servers in an array are .................." $Sn
while [ $i -lt ${#SERVERS[#]} ] ; do
#print ${SERVERS[$i]}
typeset -l s${i}=${SERVERS[$i]}
eval echo "Value of Variable is" \${s$i}
#s=\${s$i}
(( i=i+1 ))
done
#NOTE THIS LINE i value is i+1 here..
#so if you had last variable as s10=abc you are using s11 outside the loop in follwoing two lines..now its s10
let i=i-1
s=\${s$i}
eval echo "value of s is " $s
#CHANGES HERE
s=$s0
APPSERVER1=$s
echo $APPSERVER1
s=$s1
APPSERVER2=$s
echo $APPSERVER2
output...
Value of Variable is "credit":
Value of Variable is "wic":
Value of Variable is "wiccash":
Value of Variable is "sfmnp":
Value of Variable is "snap":
Value of Variable is "baked goods":
Value of Variable is "baked goods":
"credit":
"wic":

how to solve nested if issue

I am new to UNIX ... I am trying to write a bash script that takes two integers from the user and prints out the even numbers between these two numbers using an if condition. I am stuck on the nested if "an unexpected token near else" error message appears. I do not know what the error is about. Any help?
This is what I have done so far:
echo plz enter first number
read n1
echo plz enter second number
read n2
start=$n1
end=$n2
if [ start < end ] then
for (c=start;c<=end;c++)
do
if [ $((c % 2 )) -eq 0 ]; then
echo $c
fi
done
else
echo "not bigger"
fi
I think I would recommend a different approach:
((start % 2)) && ((start = 1 + start))
while ((start < end))
do
echo ${start}
(( start += 2))
done
I have tried like this:-
echo "Enter first number"
read first
echo "Enter second number"
read second
start=$first
endLine=$second
while [ $start -le $endLine ]
do
if [ $((start % 2 )) -eq 0 ]
then
echo $start "is an even number"
#else
# echo $start "is an odd number"
fi
start=`expr $start + 1`
done
You need to insert either a semicolon or a newline before the first "then":
if [ start < end ] ; then
^

Resources