How to coerce AWK to evaluate string as math expre

2020-02-10 09:24发布

Is there a way to evaluate a string as a math expression in awk?

balter@spectre3:~$ echo "sin(0.3) 0.3" | awk '{print $1,sin($2)}'
sin(0.3) 0.29552

I would like to know a way to also have the first input evaluated to 0.29552.

5条回答
冷血范
2楼-- · 2020-02-10 09:59

With gawk version 4.1.2 :

echo "sin(0.3) 0.3" | awk '{split($1,a,/[()]/);f=a[1];print @f(a[2]),sin($2)}'

It's ok with tolower(FOO) too.

查看更多
走好不送
3楼-- · 2020-02-10 10:01

Here's a simple one liner!

math(){ awk "BEGIN{printf $1}"; }

Examples of use:

math 1+1  

Yields "2"

math 'sqrt(25)'

Yeilds "5"

x=100; y=5; math "sqrt($x) + $y"

Yeilds "15"

查看更多
The star\"
4楼-- · 2020-02-10 10:01

You can just create your own eval function which calls awk again to execute whatever command you want it to:

$ cat tst.awk
{ print eval($1), sin($2) }

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

$ echo 'sin(0.3) 0.3' | awk -f tst.awk
0.29552 0.29552

$ echo '4*7 0.3' | awk -f tst.awk
28 0.29552

$ echo 'tolower("FOO") 0.3' | awk -f tst.awk
foo 0.29552
查看更多
虎瘦雄心在
5楼-- · 2020-02-10 10:06

awk lacks an eval(...) function. This means that you cannot do string to code translation based on input after the awk program initializes. Ok, perhaps it could be done, but not without writing your own parsing and evaluation engine in awk.

I would recommend using bc for this effort, like

[edwbuck@phoenix ~]$ echo "s(0.3)" | bc -l
.29552020666133957510

Note that this would require sin to be shortened to s as that's the bc sine operation.

查看更多
Root(大扎)
6楼-- · 2020-02-10 10:07

You can try Perl as it has eval() function.

$  echo "sin(0.3)" | perl -ne ' print eval '
0.29552020666134
$

For the given input,

$ echo "sin(0.3) 0.3" | perl -ne ' /(\S+)\s+(\S+)/ and print eval($1), " ", $2 '
0.29552020666134 0.3
$
查看更多
登录 后发表回答