bash:浮点运算如何工作?

时间:2014-04-06 19:44:59

标签: bash

我要撕掉我的头发:我有这个剧本:

#!/bin/bash
if [[ $# -eq 2 ]]
then
    total=0
    IFS=' '
    while read one two; do
        total=$((total+two))
    done < $2
    echo  "Total: $total"
fi

它应该将我保存的气体收据加起来以这种格式保存在文件中: 3/9/13 21.76

输出:

./getgas: line 9: 21.76: syntax error: invalid arithmetic operator (error token is ".76")

我在网上看到它可以在bash中进行浮点运算,我发现了一个有效的示例脚本,它有:

function float_eval()
{
    local stat=0
    local result=0.0
    if [[ $# -gt 0 ]]; then
        result=$(echo "scale=$float_scale; $*" | bc -q 2>/dev/null)
        stat=$?
        if [[ $stat -eq 0  &&  -z "$result" ]]; then stat=1; fi
    fi
    echo $result
    return $stat
}

看起来很棒,运行没问题

WTF正在进行中。我很容易做到这就是C但这个废话让我很生气

编辑:我没有关于awk的任何事情。它看起来很有希望,但我甚至不知道如何运行你们发布的那些单线

2 个答案:

答案 0 :(得分:3)

awk '{ sum += $2 } END { printf("Total: %.2f\n", sum); }' $2

添加由shell脚本参数$2命名的文件的第2列(awk脚本中的$2)(充满了混淆的机会)并打印最后的结果。

  

我不知道awk的任何事情。它看起来很有希望,但我甚至不知道如何运行你们发布的那些单线。

在您的脚本环境中:

#!/bin/bash
if [[ $# -eq 2 ]]
then
    awk '{ sum += $2 } END { printf("Total: %.2f\n", sum); }' $2
else
    echo "Usage: $0 arg1 receipts-file" >&2; exit 1
fi

或者只是在命令行上写下它,在$2命令之后用awk替换收据文件名。或者将其留空并从文件中重定向。或者输入日期和值。或者......,

你的脚本需要两个参数,但没有使用第一个参数,这有点令人费解。

如评论中所述,您可以将其简化为:

#!/bin/bash
exec awk '{ sum += $2 } END { printf("Total: %.2f\n", sum) }' "$@"

甚至使用shebang来充分发挥力量:

#!/usr/bin/awk -f
{ sum += $2 }
END { printf("Total: %.2f\n", sum) }

内核将为您执行awk,并且awk脚本将作为双行程序写出。当然,如果awk/bin/awk,那么你必须修复shebang线; shell在许多地方查找awk并且可能会找到它。因此坚持使用shell脚本是有好处的。如果没有指定文件,这两个版本只是对标准输入的内容进行求和,或者如果在命令行中指定了一个或多个文件,则指定所有文件中的内容。

答案 1 :(得分:1)

在bash中,你只能对整数进行操作。您发布的示例脚本使用bc,这是一种任意精度计算,包含在大多数类UNIX操作系统中。因此,脚本准备一个表达式并将其传递给bc(初始scale=...表达式配置应显示的有效数字bc

一个简化的例子是:

echo -e 'scale=2\n1.234+5.67\nquit' | bc

您也可以使用awk

awk 'BEGIN{print 1.234+5.67}'