在 Bash 中比较数字
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18668556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Comparing numbers in Bash
提问by advert2013
I'm starting to learn about writing scripts for the bash terminal, but I can't work out how to get the comparisons to work properly. The script I'm using is:
我开始学习为 bash 终端编写脚本,但我不知道如何使比较正常工作。我正在使用的脚本是:
echo "enter two numbers";
read a b;
echo "a=$a";
echo "b=$b";
if [ $a \> $b ];
then
echo "a is greater than b";
else
echo "b is greater than a";
fi;
The problem is that it compares the number from the first digit on, i.e. 9 is bigger than 10, but 1 is greater than 09.
问题是它从第一位开始比较数字,即9大于10,但1大于09。
How can I convert the numbers into a type to do a true comparison?
如何将数字转换为类型以进行真正的比较?
回答by jordanm
In bash, you should do your check in arithmetic context:
在 bash 中,您应该在算术上下文中进行检查:
if (( a > b )); then
...
fi
For POSIX shells that don't support (())
, you can use -lt
and -gt
.
对于不支持 的 POSIX shell (())
,您可以使用-lt
和-gt
。
if [ "$a" -gt "$b" ]; then
...
fi
You can get a full list of comparison operators with help test
or man test
.
您可以使用help test
或获取比较运算符的完整列表man test
。
回答by Daniel Andrei Minc?
Plain and simple
干净利落
#!/bin/bash
a=2462620
b=2462620
if [ "$a" -eq "$b" ];then
echo "They're equal";
fi
You can check out this cheatsheetif you want more number comparsions in the wonderful world of Bash Scripting.
如果您想在 Bash Scripting 的精彩世界中进行更多的数字比较,可以查看此备忘单。
Shortly, integers can only be compared with:
很快,整数只能与:
-eq # equal
-ne # not equal
-lt # less than
-le # less than or equal
-gt # greater than
-ge # greater than or equal
回答by Aleks-Daniel Jakimenko-A.
There is also one nice thing some people might not know about:
还有一件好事,有些人可能不知道:
echo $(( a < b ? a : b ))
This code will print the smallest number out of a
and b
此代码将打印出a
和中的最小数字b
回答by konsolebox
In Bash I prefer doing this as it addresses itself more as a conditional operation unlike using (( ))
which is more of arithmetic.
在 Bash 中,我更喜欢这样做,因为它更多地将自己定位为条件运算(( ))
,而不是使用它更多的是算术运算。
[[ N -gt M ]]
Unless I do complex stuffs like
除非我做复杂的事情,比如
(( (N + 1) > M ))
But everyone just has their own preferences. Sad thing is that some people impose their unofficial standards.
但每个人都有自己的喜好。可悲的是,有些人强加了他们的非官方标准。
Update:
更新:
You actually can also do this:
你实际上也可以这样做:
[[ 'N + 1' -gt M ]]
Which allows you to add something else which you could do with [[ ]]
besides arithmetic stuff.
这允许您添加[[ ]]
除算术之外的其他内容。
回答by Vangelis Tasoulas
This code can also compare floats. It is using awk (it is not pure bash), however this shouldn't be a problem, as awk is a standard POSIX command that is most likely shipped by default with your operating system.
此代码还可以比较浮点数。它使用 awk(它不是纯 bash),但是这应该不是问题,因为 awk 是标准的 POSIX 命令,它很可能默认随您的操作系统一起提供。
$ awk 'BEGIN {return_code=(-1.2345 == -1.2345) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
0
$ awk 'BEGIN {return_code=(-1.2345 >= -1.2345) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
0
$ awk 'BEGIN {return_code=(-1.2345 < -1.2345) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
1
$ awk 'BEGIN {return_code=(-1.2345 < 2) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
0
$ awk 'BEGIN {return_code=(-1.2345 > 2) ? 0 : 1; exit} END {exit return_code}'
$ echo $?
To make it shorter for use, use this function:
要缩短使用时间,请使用此功能:
compare_nums()
{
# Function to compare two numbers (float or integers) by using awk.
# The function will not print anything, but it will return 0 (if the comparison is true) or 1
# (if the comparison is false) exit codes, so it can be used directly in shell one liners.
#############
### Usage ###
### Note that you have to enclose the comparison operator in quotes.
#############
# compare_nums 1 ">" 2 # returns false
# compare_nums 1.23 "<=" 2 # returns true
# compare_nums -1.238 "<=" -2 # returns false
#############################################
num1=
op=
num2=
E_BADARGS=65
# Make sure that the provided numbers are actually numbers.
if ! [[ $num1 =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then >&2 echo "$num1 is not a number"; return $E_BADARGS; fi
if ! [[ $num2 =~ ^-?[0-9]+([.][0-9]+)?$ ]]; then >&2 echo "$num2 is not a number"; return $E_BADARGS; fi
# If you want to print the exit code as well (instead of only returning it), uncomment
# the awk line below and comment the uncommented one which is two lines below.
#awk 'BEGIN {print return_code=('$num1' '$op' '$num2') ? 0 : 1; exit} END {exit return_code}'
awk 'BEGIN {return_code=('$num1' '$op' '$num2') ? 0 : 1; exit} END {exit return_code}'
return_code=$?
return $return_code
}
$ compare_nums -1.2345 ">=" -1.2345 && echo true || echo false
true
$ compare_nums -1.2345 ">=" 23 && echo true || echo false
false
回答by Sue
If you have floats you can write a function and then use that e.g.
如果您有浮点数,您可以编写一个函数,然后使用该函数,例如
#!/bin/bash
function float_gt() {
perl -e "{if(>){print 1} else {print 0}}"
}
x=3.14
y=5.20
if [ $(float_gt $x $y) == 1 ] ; then
echo "do stuff with x"
else
echo "do stuff with y"
fi
回答by LC-datascientist
The bracket stuff (e.g., [[ $a -gt $b ]]
or (( $a > $b ))
) isn't enough if you want to use float numbers as well; it would report a syntax error. If you want to compare float numbers or float number to integer, you can use (( $(bc <<< "...") ))
.
如果您还想使用浮点数,则括号内容(例如,[[ $a -gt $b ]]
or (( $a > $b ))
)是不够的;它会报告一个语法错误。如果要将浮点数或浮点数与整数进行比较,可以使用(( $(bc <<< "...") ))
.
For example,
例如,
a=2.00
b=1
if (( $(bc <<<"$a > $b") )); then
echo "a is greater than b"
else
echo "a is not greater than b"
fi
You can include more than one comparison in the if statement. For example,
您可以在 if 语句中包含多个比较。例如,
a=2.
b=1
c=1.0000
if (( $(bc <<<"$b == $c && $b < $a") )); then
echo "b is equal to c but less than a"
else
echo "b is either not equal to c and/or not less than a"
fi
That's helpful if you want to check if a numeric variable (integer or not) is within a numeric range.
如果您想检查数字变量(整数与否)是否在数字范围内,这会很有帮助。
回答by broofa
I solved this by using a small function to convert version strings to plain integer values that can be compared:
我通过使用一个小函数将版本字符串转换为可以比较的纯整数值来解决这个问题:
function versionToInt() {
local IFS=.
parts=()
let val=1000000*parts[0]+1000*parts[1]+parts[2]
echo $val
}
This makes two important assumptions:
这提出了两个重要的假设:
- Input is a "normal SemVer string"
- Each part is between 0-999
- 输入是一个“普通的 SemVer 字符串”
- 每个部分在0-999之间
For example
例如
versionToInt 12.34.56 # --> 12034056
versionToInt 1.2.3 # --> 1002003
Example testing whether npm
command meets minimum requirement ...
示例测试npm
命令是否满足最低要求...
NPM_ACTUAL=$(versionToInt $(npm --version)) # Capture npm version
NPM_REQUIRED=$(versionToInt 4.3.0) # Desired version
if [ $NPM_ACTUAL \< $NPM_REQUIRED ]; then
echo "Please update to npm@latest"
exit 1
fi