V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
OldCarMan
V2EX  ›  Bash

shell 比较浮点数大小的问题,顺便吐槽以下 shell

  •  
  •   OldCarMan · Mar 13, 2023 · 3278 views
    This topic created in 1153 days ago, the information mentioned may be changed or developed.

    平时比较少写 shell ,最近因为需要,写 shell 时,发现 shell 的语法真的让人头大,比如简单的比较两个浮点数大小:

    a=0.1
    b=0.01
    if (( $(echo "$a > $b" |bc -l) )); then
      ehco "true"
    else
      echo "false"
    fi
    
    a=0.1
    b=0.01
    if [ $(echo "$a > $b"|bc) -eq 1 ];then
        echo "true"
    else
        echo "false"
    fi
    
    都有问题(都输出 false),常用的>,<,gt,lt 又没办法直接比较浮点数大小,简直了😂。

    PS:另外用 vim 写 shell 时经常性遇到空格之类的问题,大佬们平时是不是用 shell 比较少,是用 python 或 lua 较多吗?

    Supplement 1  ·  Mar 14, 2023
    总结一下,平时写shell时(linux运行环境),浮点数比较的几种方式:
    • 使用 #1 楼说的 awk方式,自带。
    • 使用 #15 楼说的 用python,不过我看我的centos(8.5)默认没自带,需要额外安装。
    • 使用 #16 楼说的 perl方式,自带。
    • bc库,也就是我描述里说的那种,我系统也没有自带,需要额外安装bc库。
    19 replies    2023-03-25 00:06:31 +08:00
    startisan
        1
    startisan  
       Mar 13, 2023
    OP 方式 1 输出 true 的 echo 拼写错了。

    我来补充个方式 3 ,个人更喜欢用这个,有时候数据本来就要用 awk 获取,正好 awk 就能比较:
    echo "$a" "$b" | awk '{if ($1 < $2) pring "false"; else print "true"}'
    Donahue
        2
    Donahue  
       Mar 13, 2023
    用了 linux 4 年多了,还不会 shell, 需要的时候才查...
    实在记不住这些,不常用,语法规则又那么奇怪
    OldCarMan
        3
    OldCarMan  
    OP
       Mar 13, 2023
    @startisan 是的,刚刚手打错字了,好的,谢谢大佬。
    @是啊,语法太难用了。
    刚刚在服务器重新跑了下,发现是我用 tee 命令时,有些代码片段“被吃掉了”的缘故:

    不好意思,个人粗心,让大家费心了。
    OldCarMan
        4
    OldCarMan  
    OP
       Mar 13, 2023
    不过,shell 实在一言难尽,最基本的浮点比较,也必须安装一个 bc 库才能用。
    Rache1
        5
    Rache1  
       Mar 13, 2023
    😂 我都是用 php 写,有时候需要调用 shell ,就用内置的函数执行 shell 命令。
    lakehylia
        6
    lakehylia  
       Mar 13, 2023
    @startisan 哈哈,大哥你的 print 也拼写错了
    OldCarMan
        7
    OldCarMan  
    OP
       Mar 13, 2023
    我上面#4 说错了,@startisan 这种更好使,而且不需要安装 bc 库
    OldCarMan
        8
    OldCarMan  
    OP
       Mar 13, 2023
    @Rache1 嗯嗯,脚本写的很少,之前就用 python 写过一点数据同步的,你后端如果也是 php 开发的,用 php 就够了。不过我还是不大想安装太多额外的库+业务不复杂,所以直接使用 shell 。
    churchmice
        9
    churchmice  
       Mar 13, 2023
    你具体展开说说 shell 碰到空格问题是啥问题
    你只要理解了 [ 其实也是一个命令,就不会有这么多疑惑了
    which [
    看一下就知道了
    做事要理解原理
    startisan
        10
    startisan  
       Mar 13, 2023
    @lakehylia #6 哈哈,我要被自己笑死了,我发之前还去环境上跑了下命令。
    yingqiuQAQ
        11
    yingqiuQAQ  
       Mar 13, 2023
    属于同是天涯沦落人了。。。 上次写了个内存查询 top -n 1 | grep xxx | awk '{mem_percent += $10} END {print mem_percent}' ,结果值是小数。 用 -gt 判断报错了,裂开来。
    sadfQED2
        12
    sadfQED2  
       Mar 13, 2023 via Android
    @Donahue +1 ,shell 语法永远记不住,我一般都是通过 shell 套一个 python
    crysislinux
        13
    crysislinux  
       Mar 13, 2023 via Android
    这辈子是搞不清 shell 了。之前写了个要长期运行的 bash script ,老是有内存泄露,百思不得其解,最后换了 nodejs 用同样的逻辑写就好了。。
    idontnowhat2say
        14
    idontnowhat2say  
       Mar 13, 2023
    最佳实践是把 shell 当胶水语言用,用来粘合命令,你这种情况应该用 Python 的。
    idontnowhat2say
        15
    idontnowhat2say  
       Mar 13, 2023
    ```
    #!/bin/bash
    a=0.1
    b=0.01
    python -c "print($a > $b)"
    ```

    Python 在 Linux 发行版上都自带的,你这需求就三行搞定。
    fzinfz
        16
    fzinfz  
       Mar 13, 2023
    来 2 个 perl 版:
    perl -e "print $a > $b ? qq(True\n) : qq(False\n);"
    perl -e "exit($a > $b ? 0 : 1);" && echo "True" || echo "False"
    OldCarMan
        17
    OldCarMan  
    OP
       Mar 14, 2023
    @churchmice 谢谢大佬指教,确实如你所说,shell 这方面我确实没去深入了解它的语法,主要平时很少用它,用到时才去写,空格主要是在 vim 上写时,不小心敲多了一个或少一个空格都会报错(习惯了其他语言对这方面没有那么高的要求,另外还有 idea 工作环境),你说得对,凡事从原理出发去学习。
    @yingqiuQAQ 是啊,自带基本只能做整数判断,v 友说的,或者我上面说的都要依赖其他库,不过大部分 linux 都带有了。除了那个 bc 库
    @crysislinux 主要是有时不好调试,复杂业务真不适合用它来做,如 v 友所说用来做胶水层比较好
    @idontnowhat2say 确实。
    @fzinfz 谢谢指教,新方式 get ✔
    aloxaf
        18
    aloxaf  
       Mar 24, 2023
    说真的,如果不需要考虑可移植性,写 zsh 脚本更好,很多地方比 bash 顺手多了……

    > (( 0.1 > 0.01)) && echo true || echo false
    false
    > echo $(( 0.1 + 0.01 ))
    0.11
    OldCarMan
        19
    OldCarMan  
    OP
       Mar 25, 2023
    @aloxaf 是的,只可惜,兼容性往往是一个重要的需求,当然对于那种有一定规模的脚本来说,如果引用到第三方库之类的,一般也会在脚本里声明和检测的,所以个人觉得看需求和业务量。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2505 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 64ms · UTC 00:30 · PVG 08:30 · LAX 17:30 · JFK 20:30
    ♥ Do have faith in what you're doing.