将bash表达式传递给AWK以进行浮点算术

时间:2017-07-31 04:43:07

标签: linux bash shell unix awk

我试图在bash中进行浮点运算,但由于不支持浮点数,所以试图使用AWK获得解决方案。以下是我面临的问题:

我认为这对我来说很好:

echo - | awk '{printf("%04.4f \n", (-225.2*7+30*6)/17 + (19^2)/9) }'

输出

  

-42.0301

但我的动机是“读取表达式”并将计算值修正为4位小数,因此尝试下面的代码输入相同的表达式(-225.2 * 7 + 30 * 6)/ 17 +(19 ^ 2)/ 9)并给出不正确的值(我猜变量作为字符串传递给awk):

read inpt 
echo - | awk -v input=$inpt '{printf("%04.4f \n", input) }'

输出

  

0.0000

注意:请忽略此示例表达式中第二个+周围的空格,我可以使用sed或类似方法删除(使用空格我在从bash传递变量时在awk中获得语法错误)。

非常感谢任何帮助。提前致谢

PS:我的案例中的bash版本是“bash-4.2”。我想它的bash版本阻止我使用许多其他选项。

4 个答案:

答案 0 :(得分:4)

您无法开箱即用地评估变量中的数据。在这种情况下,您需要编写算术求值程序或使用预先存在的算术求值程序,如https://github.com/radare/radare2-bindings/blob/master/awk/calc.awk。修复缺少的括号并正确引用表达式后,您可以:

void Awake()
{
    InitGameVariables();
}

答案 1 :(得分:1)

我推荐并赞成詹姆斯布朗的回答。但是如果你现在需要一些东西而现在没有外部依赖,你可以简单地将输入插入到脚本中。

awk "END { printf("%04.4f\n", $input) }" </dev/null

这在功能上等同于使用eval所以如果没有部署你知道你可以信任输入的地方(例如因为它来自受控过程,而不是实际用户),你需要执行一些某种清理(如果输入不是格式良好的Awk表达式,那么即使这样也可能应对奇怪或彻头彻尾的误导性错误消息)。

read -p "Input an Awk expression: " input
case $input in
  *[!-+/*()^%0-9]*)
    echo "$0: invalid input" >&2
    exit 1;;
esac
awk ...

还要注意避免基本无用echo的构造。重定向来自/dev/null的输入并将您的代码放入END(或BEGIN)块是一种标准技术,可以在不需要任何输入的情况下运行任意一段Awk脚本。

答案 2 :(得分:0)

首先,我没有看到命令有任何错误,它应该工作。如果问题仍然存在,请再次尝试发布的确切命令并提供确切的详细信息。

但是,如果您只需要格式化输出,则可以直接使用printf进行输出。

$ read input
12.34
$ printf '%4.4f' $input
12.3400

编辑:

如果您需要在执行某些计算后格式化输出,则可以使用bc。 (awk仍应有效)

$ echo "scale=4; (-225.2*7+30*6)/17+(19^2)/9" | bc
-42.0300

您可以照常使用表达式中的变量

$ read inpt
1234
$ echo "scale=4; $inpt * 0.01" | bc
12.34

答案 3 :(得分:-1)

这是你在找什么?

 echo "25 50"| awk '{print $2,"/",$1}' | bc