如果条件在一定范围内有2个不同的值(边界)

假设我有一个坐标(x,y),我想做两个类别:好或坏。

我不知道如何将它放入单词或关键字,所以我创建了一个我想要的例子。

我创建了一个像这样的bash脚本:

x=3.5 #(example) y=-2.5 #(example) if [ $x -ge 0.1 -a $x -le 5.5 ] && [ $y -ge -5.9 -a $y -le -0.1 ]; then cat="good"; elif [ $x -ge 5.5 -a $x -le 10.5 ] && [ $y -ge -10.9 -a $y -le -5.9 ]; then cat="bad"; fi echo "$cat" 

在该脚本上,我想知道x是否在0.1到5.5(0.1 <x <5.5)的范围内,并且在-5.9到-0.1(-5.9 <y <-0.1)内的y是真的,那么它给出的结果是good 。 不同的边界应该会产生bad结果。

我运行它并将结果作为预期的整数表达式给出。

当我尝试用运算符> (或< )替换运算符-ge (或-le ),或者尝试添加方括号和我能想到的任何东西时,它会给出相同的错误或者没有给出结果。

我该怎么办呢?

Bash只能做整数数学运算。 如果值具有固定的小数位数,则可以删除. (使用sedawk或您喜欢的任何命令)并比较结果值。 例如,如果它们只有一个小数位,如10.0, 0.4, 2.2 ,则删除. 将它们乘以10,得到100, 04, 22 (使用旧的测试命令[ ,前导0 s对于整数比较无关紧要)。 当然,你必须相应地增加边界。

或者,您可以使用bc ,它将使用任意精度浮点数。 bc读取stdin ,所以你可以,例如,回显表达式并将其传递给bc ,如下所示:

 echo "$x>=0.1 && $x<=5.5" | bc 

如果表达式为true ,则输出为1 ,否则为0 。 如果您想了解有关其语法的更多信息,请阅读手册( man bc )。

要将其合并到脚本中,可以使用如下命令替换:

 if [ $(echo "$x>=0.1 && $x<=5.5" | bc) -eq 1 ] ; then cat="good"; 

请注意,我们仍然需要检查bc命令的输出是否为1 ,因为[ 0 ]也将评估为true

最后,你的例子使用bc

 x=6.5 #(example) y=-7.5 #(example) if [ $(echo "$x>=0.1 && $x<=5.5 && $y>=-5.9 && $y<=-0.1" | bc) -eq 1 ] ; then cat="good"; elif [ $(echo "$x>=5.5 && $x<=10.5 && $y>=-10.9 && $y<=-5.9" | bc) -eq 1 ]; then cat="bad"; fi echo "$cat" 

由于在括号内部具有难以读取的字符串使其更容易出错,因此可以使用bash函数和变量,如以下示例所示。 如果要添加具有不同范围的其他elif子句,这可能很有用。 (感谢wjandrea提供的有用提示)

 x=6.5 #(example) y=-6.5 #(example) boundsGood="0.1 5.5 -5.9 -0.1" boundsBad="5.5 10.5 -10.9 -5.9" # Paramaters in following order: x, y, xmin, xmax, ymin, ymax; bounds are inclusive. function in_bounds { local x=$1 local y=$2 local x_min=$3 local x_max=$4 local y_min=$5 local y_max=$6 [ $(echo "$x >= $x_min && $x <= $x_max && $y >= $y_min && $y <= $y_max" | bc) -eq 1 ] } if in_bounds $x $y $boundsGood ; then cat="good"; elif in_bounds $x $y $boundsBad ; then cat="bad"; fi echo "$cat" 

使用printf替代版本的in_bounds函数(感谢steeldriver ):

 # Paramaters in following order: x, y, xmin, xmax, ymin, ymax; bounds are inclusive. function in_bounds { [ $(printf "x = %f; y = %f; xmin = %f; xmax = %f; ymin = %f; ymax = %f; x >= xmin && x <= xmax && y >= ymin && y <= ymax\n" "$1" "$2" "$3" "$4" "$5" "$6" | bc) -eq 1 ] } 

如果绝对需要保留在shell脚本中 – 将变量添加到awk嵌入式脚本中以将xy值传递到awk的环境中并使用ENVIRON["variable_name"]来访问它们; 并让它完成打印所需字符串的工作(或将整个脚本包装到$(...)以保存输出)。

如果没有必要,请取消shell脚本部分,然后让awk单独处理所有内容。

 #!/bin/sh x=3.5 y=-2.5 x="$x" y="$y" awk 'BEGIN{ print ENVIRON["x"],ENVIRON["y"]; if ((ENVIRON["x"] >= 0.1) && (ENVIRON["x"] <= 5.5) \ && (ENVIRON["y"] >= -5.9) && (ENVIRON["y"] <= -0.1)){ print "good"; } else if ((ENVIRON["x"] >= 5.5) && (ENVIRON["x"] <= 10.5) \ && (ENVIRON["y"] >= -10.9) && (ENVIRON["y"] <= -5.9)){ print "bad"; } }' # End of awk