如何将字符串输入 awk 进行数学计算?

如何将字符串输入 awk 进行数学计算?
#!/bin/sh --

expression_to_evaluate='12 + 3'

printf '%s\n' "Arithemtic Expansion: $(( $expression_to_evaluate ))"

printf '%s' 'bc: '
printf '%s\n' "$expression_to_evaluate" | bc

printf '%s' 'awk: '
awk -v expression_to_evaluate="$expression_to_evaluate" -- 'BEGIN{printf "%d\n", expression_to_evaluate}'

输出:

Arithemtic Expansion: 15
bc: 15
awk: 12

awk返回 12 而不是 15。我怎样才能输入一个字符串来awk进行数学计算?

答案1

虽然这有效,但我建议不要这样做,因为除非您控制 的来源expression_to_evaluate,否则这是一个安全风险:

$ expression_to_evaluate='12 + 3'
$ awk "BEGIN{printf \"%d\n\", $expression_to_evaluate}"
15

答案2

awk没有办法计算以字符串形式提供的通用算术表达式。 bc另一方面,它接受一个表达式并对其求值,就像 shell 一样。

您是否想将字符串计算为 中的数学表达式awk,您必须将表达式注入为代码awk程序中(可能会产生代码注入漏洞),或者只是为您想要评估的表达式类型编写自己的解析器(这是常见的计算机科学作业)。

您可以12awk代码中得到,因为 的值expression_to_evaluate在转换为整数时可以一直转换到字符串中的空格字符。这就是strtol()C 库函数将字符串转换为整数时的工作原理,并且awk很可能在幕后使用它。

答案3

编辑

我忘记了我很久以前就写了这个函数并让它自动导入到awk中。

eval函数的代码如下:

function eval(str,cmd,line,ret) {
    cmd = "gawk \047BEGIN{print " str "; exit}\047"
    if ( (cmd | getline line) > 0 ) {
        ret = line
    }
    close(cmd)
    return ret
}

如果将其放入文件中,则可以在脚本之前导入它

awk -i fileWithFunction.awk '{print eval($1)}'

我有 awk 作为一个函数,所以我永远不需要考虑导入我经常使用的函数。

awk () {
    awk -i awk_functions.awk "$@"
}

对于造成的混乱,我深表歉意!

原帖

awkeval()中的(注意,您必须从文件导入此函数,或者将其放入 awk 脚本中!参见上文。)函数将执行您想要的操作。这可能是 gawk 特有的,但如果你不使用gawk那么你应该是:)

例子

$ expression="1+1"
$ echo | awk -v expression=$expression '{print eval(expression)}'
2

$ expression="2^10"
$ echo | awk -v expression=$expression '{print eval(expression)}'
1024

您还可以创建一个简单的 awk 程序输入来获取输入的值并对其进行处理

$ awk 'BEGIN{printf "Expression:"}{print eval($0);printf "Expression:"}'
Expression:2^29
536870912
Expression: log(10)/log(30)
0.676992
Expression: I love cake

答案4

echo $expression_to_evaluate | awk -F "+" '{print ($1+$2)}'

相关内容