【问题标题】:comparison of integer and floating point numbers in shell scriptshell脚本中整数和浮点数的比较
【发布时间】:2013-12-24 15:18:34
【问题描述】:

在shell脚本中,我们如何比较(整数和浮点),(浮点和浮点),(浮点和整数),(整数和整数)只有一个if条件。

我有几个例子像

 set X=3.1
  set Y=4.1
  if [ $X < $Y ] then
    echo "wassup"
  endif

但从 cron 作业运行上述内容似乎不起作用。

【问题讨论】:

标签: linux shell unix


【解决方案1】:

在 bash 中执行浮点运算的方法是使用bc,它在几乎所有的 linux 发行版上都可用。

# bc will return 0 for false and 1 for true
if [ $(echo "23.3 > 7.3" | bc) -ne 0 ] 
then 
  echo "wassup"
fi

Linux 杂志上有一个good article 可用,关于使用 bc 在 bash 中的浮点数学。

【讨论】:

  • 我尝试了以下操作并得到了预期的一元操作错误
  • 有趣。我在这里工作正常。嗯。您的错误意味着(我认为)是 $(echo "$a &gt; $b" | bc) 没有返回值。你可以自己试试 subshel​​l 吗?
  • IE:您的变量未正确分配。例如,echo $X 将是一个空行。
【解决方案2】:

Bah 本身只处理整数。使用 bc:

echo "$X>$Y" | bc 
0
echo "$X<$Y" | bc 
1

您无需担心规模问题。它只是为了输出格式的preocision:

X=3.000001
Y=3.0001
echo "$X>$Y" | bc 
0
echo "$X<$Y" | bc 
1
echo "scale=1;$X<$Y" | bc 
1

【讨论】:

    【解决方案3】:

    以下示例适用于 bash shell。

     X=3.1
     Y=4.1
     if [ $X -le $Y ]
     then
        echo "wassup"
     fi
    

    你可能想学习shell脚本here

    【讨论】:

    • 这在这里不起作用,因为 bash 不处理浮点数:$ test "34.4" -gt "5.4" -&gt; bash: test: 34.4: integer expression expected
    • 我不怀疑你的诚意 :) 我只是说这不能保证在 Linux 上工作bash --version 给我GNU bash, version 4.2.8(1)-release (x86_64-pc-linux-gnu)
    【解决方案4】:

    编辑。基于这个答案的 cmets(感谢 user unknownglenn jackman),似乎当使用 bc 来表示 true/false 测试,所需的bash 测试很简单:

    • (( $(echo "$X &lt; $Y" |bc) )) ...查看下面的测试结果和脚本

    然而,旧式 bash [ ] 测试需要与 -ne 0 进行比较。


    bash 本身不处理浮点数,但您可以调用诸如bc 之类的实用程序

    来自man bc - 一种任意精度的计算器语言

    X=3.1
    Y=4.1
    # This test has two superfluous components. 
    # See EDIT (above) and TESTS below
    if (($(echo "scale=9; $X < $Y" |bc)!=0)) ;then
        echo "wassup"
    fi
    

    测试结果:

    if [  "1"  ]   true
       [  "1"  ]   true
    if [  "0"  ]   true
       [  "0"  ]   true
    
    if [   1   ]   true
       [   1   ]   true
    if [   0   ]   true
       [   0   ]   true
    
    if (( "1" ))   true
       (( "1" ))   true
    if (( "0" ))   false
       (( "0" ))   false
    
    if ((  1  ))   true
       ((  1  ))   true
    if ((  0  ))   false
       ((  0  ))   false
    
    echo "1<1"|bc  true
    echo "1<0"|bc  true
    

    测试脚本:

    printf 'if [  "1"  ]   '; if [ "1" ]; then echo true; else echo false; fi
    printf '   [  "1"  ]   ';    [ "1" ]  &&   echo true  ||   echo false
    printf 'if [  "0"  ]   '; if [ "0" ]; then echo true; else echo false; fi
    printf '   [  "0"  ]   ';    [ "0" ]  &&   echo true  ||   echo false
    echo  
    printf 'if [   1   ]   '; if [  1  ]; then echo true; else echo false; fi
    printf '   [   1   ]   ';    [  1  ]  &&   echo true  ||   echo false
    printf 'if [   0   ]   '; if [  0  ]; then echo true; else echo false; fi
    printf '   [   0   ]   ';    [  0  ]  &&   echo true  ||   echo false
    echo  
    printf 'if (( "1" ))   '; if (("1")); then echo true; else echo false; fi
    printf '   (( "1" ))   ';    (("1"))  &&   echo true  ||   echo false
    printf 'if (( "0" ))   '; if (("0")); then echo true; else echo false; fi
    printf '   (( "0" ))   ';    (("0"))  &&   echo true  ||   echo false
    echo  
    printf 'if ((  1  ))   '; if (( 1 )); then echo true; else echo false; fi
    printf '   ((  1  ))   ';    (( 1 ))  &&   echo true  ||   echo false
    printf 'if ((  0  ))   '; if (( 0 )); then echo true; else echo false; fi
    printf '   ((  0  ))   ';    (( 0 ))  &&   echo true  ||   echo false
    echo
    printf 'echo "1<1"|bc  '; echo "1<1"|bc >/dev/null  && echo true || echo false 
    printf 'echo "1<0"|bc  '; echo "1<0"|bc >/dev/null  && echo true || echo false 
    

    【讨论】:

    • scale 是多余的,如果你只是想测试真假。 !=0 也是多余的 - 已经完成了。
    • !=0 不是 多余的:bc 打印 0 或 1 表示假或真。在这两种情况下,退出状态都是零。因此,您必须将命令输出与某些内容进行比较。
    • 好主意,但错误:if (($(echo "$X &gt; $Y" | bc))) ; then echo wassup; else echo pussaw; fi。原因:$(...) 捕获输出。 ((...)) 评估。
    • 看来你们都是对的,对于不同的格式 :) ...我已经在我的答案中添加了测试。
    • @glennjackman:我忘了给你的通知标记。对不起。
    猜你喜欢
    • 2015-01-20
    • 2011-04-19
    • 2016-05-24
    • 2016-02-08
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 2012-05-13
    相关资源
    最近更新 更多