比较Bash中的数字

我开始学习如何为bashterminal编写脚本,但是我无法弄清楚如何让比较正常工作。 我确定这对你们很多人来说是非常基本的,我似乎无法在任何地方find我的问题的答案(或者至less我不完全确定要search什么)。 我使用的脚本是:

echo "enter two numbers"; read ab; 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是大于10000,但1大于09.我怎样才能将数字转换成一个types做一个真正的比较?

在bash中,你应该在算术上下文中进行检查:

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

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

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

您可以通过help test获得比较运算符的完整列表。

干净利落

 #!/bin/bash a=2462620 b=2462620 if [ "$a" -eq "$b" ];then echo "They're equal"; fi 

如果你想在Bash Scripting的美妙世界中进行更多的数字比较,你可以查看这个cheatsheet 。

不久之后,整数只能与:

 -eq # equal -ne # not equal -lt # less than -le # less than or equal -gt # greater than -ge # greater than or equal 

也有一些人可能不知道的好东西:

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

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

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

 [[ N -gt M ]] 

除非我做复杂的东西

 (( (N + 1) > M )) 

但是每个人都有自己的喜好。 可悲的是有些人强加了非正式的标准。

更新:

你其实也可以这样做:

 [[ 'N + 1' -gt M ]] 

它允许你添加一些其他的东西,除了算术的东西外你还可以用[[ ]]来做什么。

这段代码也可以比较浮点数。 它使用的是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 $? 

为了缩短使用时间,请使用以下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=$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 

我通过使用小函数将版本string转换为可以比较的纯整数值来解决此问题:

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

这使得两个重要的假设:

  1. input是一个“ 正常SemVerstring ”
  2. 每个部分在0-999之间

例如

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

示例testingnpm命令是否满足最低要求…

 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