I have loop which writes to file, but I want to write each 0.5 value to the file. I tried with let count+=0.5 but that didn't work somehow. Is this possible?
Script:
#!/bin/bash
COUNTER=50
count=0
until [ $COUNTER -lt 20 ]; do
echo $count >> value.txt
echo COUNTER $COUNTER
let COUNTER-=1
let count+=0.5
sleep 1
done
bash doesn't do floating-point arithmetic natively; you need to use an external tool. -= is also not a supported operator.
until [ "$COUNTER" -lt 20 ]; do
printf "%0.1f\n" "$count"
echo "COUNTER $COUNTER"
count=$(bc <<< "$count + 0.5")
COUNTER=$((COUNTER - 1))
sleep 1
done > value.txt
Related
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?
I would like to download file with the format cars000.txt, cars003.txt,cars006.txt, till cars105.txt...interval of 3 as you can see
I use the following code in ksh, but after downloading cars012.txt, it fails, it begins to download cars13.txt,...and I don't wish it. What does it fails in the code?
FHR=000
while [ $FHR -le 105 ]
do
file=cars${FHR}.txt
wget http://${dir_target}/${file}
(( FHR = $FHR + 03 ))
echo $FHR
if [[ $FHR -le 10 ]]; then FHR="00"$FHR
else FHR="0"$FHR
fi
done
You should decide: is FHR a string, a decimal or an octal.
You are mixing them currently.
Try the next improvement:
FHR=0
while [ ${FHR} -le 105 ]; do
file=cars${FHR}.txt
(( FHR = FHR + 3 ))
echo Without leading zero: FHR=${FHR}
if [[ $FHR -le 10 ]]; then
echo "FHR=00${FHR}"
else
echo "FHR=0${FHR}"
fi
sleep 1
done
(The next improvement might be using printf or awk and no zero for 102/105)
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`
I need to perform a calculation(addition/multiplication) using the command line input.
For an example: I'm executing the below ./calculation.sh 1 2 3 4 5. It has to sum up the output as 15. Any idea to this ? I've tried with the below logic but couldn't make it.
set -x
while [ $# -gt 0 ]
do
expr $1 + 1
shift
done
OUTPUT=0
for i in $*; do
OUTPUT=$(($OUTPUT + $i))
done
echo $OUTPUT
You need to make use of a variable to save the result of expr. Moreover, +1 doesn't seem to make much sense. You probably wanted to replace that with the variable itself.
You need to print the variable at the end.
Try:
set -x
res=0
while [ $# -gt 0 ]
do
res=`expr $1 + $res`
shift
done
echo $res
Try
set -x
sum=0
while [ $# -gt 0 ]
do
sum=$(expr "$sum" + "$1")
shift
done
echo "sum: $sum"
And it's simpler in bash:
sum=0
for i; do
(( sum += i ))
done
echo "sum: $sum"
I'm trying to slow down my infinite loop if CPU load exceeds certain limit, but, its just not working out right, below is the code. The if condition always results true
c=1
while [ $c -le 1 ]
do
#echo "Welcome $c times"
#php BALHABLH.php
IN=$(cat /proc/loadavg);
set -- "$IN"
IFS=" "; declare -a Array=($*)
echo "${Array[#]}"
echo "${Array[0]}"
echo "${Array[1]}"
#var = ${Array[1]}
x=$(expr "${Array[1]}" )
if [ $x > 0.91 ]
then
echo "CPU LOAD > 0.91"
sleep 2
fi
(( c++ ))
done
You need to use bc for floating point comparison and use (( ... )) for arithmetic expressions:
if (( $(bc -l <<< "$x > 0.91") == 1 ))
Also don't use cat, use:
IN=$(</proc/loadavg)
Bash cannot use floating point arithmetic. You could do something like this:
if [ $( echo "$x > 0.91" | bc ) -eq 1 ]; then
Bash only handles integers. To handle floats pipe to bc like this:
[ $(echo " $x > 0.91" | bc -l) -eq 1 ]
bc returns 1 if the comparison is true. We compare with 1 (using the -eq operator).
Validation
$ cat test.sh
#!/bin/bash
x="$1"
if [ $(echo " $x > 0.91" | bc -l) -eq 1 ]; then
echo greater;
else
echo smaller;
fi
$ ./test.sh 0.5
smaller
$ ./test.sh 1.5
greater
You can also simplify your script a bit like this:
#!/bin/bash
c=10
for (( i=1;i<=c;i++ )); do
load=$(awk '{print $2}' /proc/loadavg)
echo "$i: load is $load"
if (( $(echo "$load > 0.91" | bc) == 1 )); then
echo "CPU LOAD > 0.91"
sleep 2
fi
done