749

我无法进行数字比较:

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;

问题是它从第一个数字开始比较数字,即9大于10,但1大于09。

如何将数字转换为类型以进行真正的比较?

4

9 回答 9

1151

在 Bash 中,您应该在算术上下文中进行检查:

if (( a > b )); then
    ...
fi

对于不支持的 POSIX shell (()),您可以使用-lt-gt

if [ "$a" -gt "$b" ]; then
    ...
fi

help test您可以使用or获得比较运算符的完整列表man test

于 2013-09-07T00:48:12.037 回答
258

像这样:

#!/bin/bash

a=2462620
b=2462620

if [ "$a" -eq "$b" ]; then
  echo "They're equal";
fi

整数可以与这些运算符进行比较:

-eq # Equal
-ne # Not equal
-lt # Less than
-le # Less than or equal
-gt # Greater than
-ge # Greater than or equal

请参阅此备忘单

于 2016-01-15T09:06:35.457 回答
55

还有一件好事,有些人可能不知道:

echo $(( a < b ? a : b ))

此代码将打印出最小的数字ab

于 2013-09-07T01:11:17.637 回答
35

在 Bash 中,我更喜欢这样做,因为它更像是一个条件操作,而不像 using (( ))which 更多的是算术。

[[ n -gt m ]]

除非我做复杂的事情,比如

(( (n + 1) > m ))

但每个人都有自己的喜好。可悲的是,有些人强加了他们的非官方标准。

你也可以这样做:

[[ 'n + 1' -gt m ]]

这允许您添加[[ ]]除算术之外的其他内容。

于 2013-09-07T01:02:32.780 回答
9

此代码还可以比较浮点数。它正在使用 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 $?

为了缩短使用时间,请使用此功能:

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=$1
   op=$2
   num2=$3
   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
于 2015-03-25T11:49:38.613 回答
8

如果您还想使用浮点数,括号内容(例如,[[ $a -gt $b ]](( $a > $b )))是不够的;它会报告语法错误。如果要将浮点数或浮点数与整数进行比较,可以使用(( $(bc <<< "...") )).

例如,

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

您可以在 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

如果您想检查数值变量(整数与否)是否在数值范围内,这将很有帮助。

于 2019-10-20T02:43:38.210 回答
6

如果你有浮点数,你可以编写一个函数然后使用它。例如,

#!/bin/bash

function float_gt() {
    perl -e "{if($1>$2){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
于 2018-03-21T17:02:04.770 回答
3

我通过使用一个小函数将版本字符串转换为可以比较的纯整数值来解决这个问题:

function versionToInt() {
  local IFS=.
  parts=($1)
  let val=1000000*parts[0]+1000*parts[1]+parts[2]
  echo $val
}

这做出了两个重要的假设:

  1. 输入是一个“普通的 SemVer 字符串
  2. 每个部分在0-999之间

例如

versionToInt 12.34.56  # --> 12034056
versionToInt 1.2.3     # -->  1002003

示例测试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
于 2017-03-08T20:37:24.093 回答
2

一站式解决方案。

a=2
b=1
[[ ${a} -gt ${b} ]] && echo "true" || echo "false"
于 2021-12-31T14:35:06.943 回答