如果条件在一定范围内有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只能做整数数学运算。 如果值具有固定的小数位数,则可以删除.
(使用sed
或awk
或您喜欢的任何命令)并比较结果值。 例如,如果它们只有一个小数位,如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
嵌入式脚本中以将x
和y
值传递到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