Как заставить AWK оценивать строку как математическое выражение? - PullRequest
0 голосов
/ 12 января 2019

Есть ли способ оценить строку как математическое выражение в awk?

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

Я хотел бы знать, как можно также оценить первый вход в 0,29552.

Ответы [ 4 ]

0 голосов
/ 14 января 2019

Вы можете попробовать Perl, так как он имеет функцию eval ().

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

Для данного ввода

$ echo "sin(0.3) 0.3" | perl -ne ' /(\S+)\s+(\S+)/ and print eval($1), " ", $2 '
0.29552020666134 0.3
$
0 голосов
/ 12 января 2019

Вы можете просто создать свою собственную функцию eval, которая снова вызывает awk для выполнения любой команды, которую вы хотите:

$ 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
0 голосов
/ 13 января 2019

С версией gawk 4.1.2:

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

Это нормально с tolower(FOO) тоже.

0 голосов
/ 12 января 2019

awk не имеет функции eval(...). Это означает, что вы не можете выполнять перевод строки в код на основе ввода после инициализации программы awk. Хорошо, возможно, это можно сделать, но не без написания вашего собственного механизма анализа и анализа в awk.

Я бы рекомендовал использовать bc для этого усилия, например

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

Обратите внимание, что для этого потребуется sin сократить до s, поскольку это bc операция синуса.

...