How can I compare floating number in a shell script?
ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Introduction to Linux - A Hands on Guide
This guide was created as an overview of the Linux Operating System, geared toward new users as an exploration tour and getting started guide, with exercises at the end of each chapter.
For more advanced trainees it can be a desktop reference, and a collection of the base knowledge needed to proceed with system and network administration. This book contains many real life examples derived from the author's experience as a Linux system and network administrator, trainer and consultant. They hope these examples will help you to get a better understanding of the Linux system and that you feel encouraged to try out things on your own.
Click Here to receive this Complete Guide absolutely free.
How can I compare floating number in a shell script?
root@server1 [/]# ./ss3
./ss3: [: 3.1: integer expression expected
root@server1 [/]# cat ss3
#!/bin/bash
X=3.1
Y=3.2
empty_string=""
if [ $X -lt $Y ] # is $X less than $Y ?
then
echo "\$X=${X}, which is greater than \$Y=${Y}"
fi
Why does it say integer expression expected? How can I compare floats?
===========================================
It wont even work in C shell
root@server1 [/]# ./ss3
if: Badly formed number.
root@server1 [/]# cat ss3
#! /bin/csh -f
set X=3.1
set Y=4.1
if ( $X < $Y ) then
echo "\$X=${X}, which is greater than \$Y=${Y}"
endif
I tried it in perl but it doesnt store the right value to $a as it does in bash or cshell:
root@server1 [/]# cat ss4
#!/usr/bin/perl
$a=`uptime | awk -F'[, ]*' '{print $11}'`;
#echo "a = $a"
if ( $a > 5.2 ){
print $a;
}
1 #!/bin/bash
2 X=3.1
3 Y=3.2
4 empty_string=""
5
6 if [ $X < $Y ] # is $X less than $Y ?
7 then
8 echo "\$X=${X}, which is less than \$Y=${Y}"
9 elif [ $X > $y ]
10 then
11 echo "\$X=${X}, which is greater than \$Y=${Y}"
12 fi
Re: How can I compare floating number in a shell script?
Quote:
Originally posted by abefroman root@server1 [/]# ./ss3
./ss3: [: 3.1: integer expression expected
root@server1 [/]# cat ss3
#!/bin/bash
X=3.1
Y=3.2
empty_string=""
if [ $X -lt $Y ] # is $X less than $Y ?
then
echo "\$X=${X}, which is greater than \$Y=${Y}"
fi
Why does it say integer expression expected? How can I compare floats?
===========================================
It wont even work in C shell
root@server1 [/]# ./ss3
if: Badly formed number.
root@server1 [/]# cat ss3
#! /bin/csh -f
set X=3.1
set Y=4.1
if ( $X < $Y ) then
echo "\$X=${X}, which is greater than \$Y=${Y}"
endif
As other people have already posted there are ways to work this out but in general case you should know this:
Quote:
Bash does not understand floating point arithmetic. It treats numbers containing a decimal point as strings.
Quote:
When not to use shell scripts
*
Resource-intensive tasks, especially where speed is a factor (sorting, hashing, etc.)
*
Procedures involving heavy-duty math operations, especially floating point arithmetic, arbitrary precision calculations, or complex numbers (use C++ or FORTRAN instead)
*
Cross-platform portability required (use C instead)
*
Complex applications, where structured programming is a necessity (need type-checking of variables, function prototypes, etc.)
*
Mission-critical applications upon which you are betting the ranch, or the future of the company
*
Situations where security is important, where you need to guarantee the integrity of your system and protect against intrusion, cracking, and vandalism
*
Project consists of subcomponents with interlocking dependencies
*
Extensive file operations required (Bash is limited to serial file access, and that only in a particularly clumsy and inefficient line-by-line fashion)
*
Need multi-dimensional arrays
*
Need data structures, such as linked lists or trees
*
Need to generate or manipulate graphics or GUIs
*
Need direct access to system hardware
*
Need port or socket I/O
*
Need to use libraries or interface with legacy code
*
Proprietary, closed-source applications (shell scripts put the source code right out in the open for all the world to see)
Last edited by perfect_circle; 06-24-2005 at 01:30 PM.
yea, you can't do very much arithmetic in bash directly. you can pipe some commands to the calculator 'bc', and it will spit out the answer to the standard output.
> echo 3.14 + 5.16 | bc
8.30
as for a comparison, bc has some comparison capability, but you may be able to do something similar with a different tool, by piping it the comparison, and looking at what it returns.
Actually, that doesn't work exactly. Even if you set X to 3.5, it will still say that X is less than Y.
Quote:
Originally Posted by MoneyCat
This code below works:
Code:
1 #!/bin/bash
2 X=3.1
3 Y=3.2
4 empty_string=""
5
6 if [ $X < $Y ] # is $X less than $Y ?
7 then
8 echo "\$X=${X}, which is less than \$Y=${Y}"
9 elif [ $X > $y ]
10 then
11 echo "\$X=${X}, which is greater than \$Y=${Y}"
12 fi
Another option in shell is to call expr for doing fp calcs.
I'm curious as to why you think Perl doesn't work, but then I noticed (commented out) 'echo', which is not a perl cmd/keyword.
Try
print "$a\n";
In fact, I'd just call uptime and then do the string parse in perl, instead of piping through awk.
Some shells like zsh understand floating point. Here's a sample comparing bash and zsh. It writes a file t1, then asks bash and zsh to execute it:
Code:
#!/bin/sh
# @(#) s1 Compare bash and zsh for arithmetic.
set -o nounset
cat >t1 <<'EOF'
if [ -n "$BASH_VERSION" ]
then
echo " From bash, version :$BASH_VERSION:"
elif [ -n "$ZSH_VERSION" ]
then
echo " From zsh, version :$ZSH_VERSION:"
else
echo " Unknown shell."
fi
float X Y
(( X = 3.0 + 0.5 ))
(( Y = 33.0 / 10.0 ))
if (( $X < $Y )) # is $X less than $Y ?
then
echo "\$X=${X}, which is less than \$Y=${Y}"
elif (( $X > $Y ))
then
echo "\$X=${X}, which is greater than \$Y=${Y}"
fi
EOF
echo
bash t1
echo
zsh t1
exit 0
Producing:
Code:
% ./s1
From bash, version :2.05b.0(1)-release:
t1: line 12: float: command not found
t1: line 13: ((: X = 3.0 + 0.5 : syntax error in expression (error token is ".0+ 0.5 ")
t1: line 14: ((: Y = 33.0 / 10.0 : syntax error in expression (error token is ".0 / 10.0 ")
$X=3, which is less than $Y=33
From zsh, version :4.2.4:
$X=3.500000000e+00, which is greater than $Y=3.300000000e+00
Just in case anyone is directed to this page, rather than doing some horribly convoluted solution, the following will work on most systems (even ones that dont have bc and perl) - eg many small devices running busybox.
As ahh said - 'awk' is probably your best friend here:
Code:
# Return the value of an operation
float_val() {
echo | awk 'END { print '"$1"'; }'
}
Or more usefully
Code:
# Return status code of a comparison
float_test() {
echo | awk 'END { exit ( !( '"$1"')); }'
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.