文字列を数式として評価するようにAWKに強制する方法

How to coerce AWK to evaluate string as math expression? – StackOverflow

これすっごい知りたい.というか,知りたかった.Awkに限った事ではない(と思う).
コメント欄に似たような事を書いている人がいるけど,Pythonに逃げれば,

%%bash
time {
echo 'sin(0.3) 0.3' |
python -c """
import sys
from math import *
for line in sys.stdin.readlines():
    for s in line.split():
        print(eval(s), end=' ')
"""
}
0.29552020666133955 0.3 
real    0m0.061s
user    0m0.040s
sys 0m0.023s

とできるけど,やりたい事に対してあまりにも高価過ぎる.

限定的な解法だけど,関数作るしか無いのだろうか.

%%bash
time {
echo 'sin(0.3) 0.3' |
awk '{for(i=1;i<=NF;i++)$i=calc($i)}1

function calc(x){
    match(x,/[0-9.-]+/)
    val=substr(x,RSTART,RLENGTH)
    if(x~/sin/){
        res=sin(val)
    }else if(x~/cos/){
        res=cos(val)
    }else{
        res=x
    }
    return res
}'
}
0.29552 0.3

real    0m0.004s
user    0m0.002s
sys 0m0.002s
%%bash
time {
echo 'sin(0.3) 0.3' |
awk -v CONVFMT=%.16g '
{for(i=1;i<=NF;i++)$i=calc($i)}1

function calc(x){
    match(x,/[0-9.-]+/)
    val=substr(x,RSTART,RLENGTH)
    if(x~/sin/){
        res=sin(val)
    }else if(x~/cos/){
        res=cos(val)
    }else{
        res=x
    }
    return res
}'
}
0.2955202066613395 0.3

real    0m0.004s
user    0m0.002s
sys 0m0.003s
%%bash
time {
echo 'sin(0.3) 0.5*0.2 0.3' |
mawk -v CONVFMT=%.16g '
{for(i=1;i<=NF;i++)$i=calc($i)}1
 
function calc(x){
    match(x,/[0-9.-]+/)
    val=substr(x,RSTART,RLENGTH)
    if(x~/sin/){
        res=sin(val)
    }else if(x~/cos/){
        res=cos(val)
    }else{
        cmd="echo "x" | bc -l"
        v=((cmd | getline line)>0 ? line : -1)
        close(cmd)
        sub("^.","0.",v)
        res=v
    }
    return res
}'
}
0.2955202066613395 0.10 0.3

real    0m0.017s
user    0m0.004s
sys 0m0.015s

この糞ブログはコードが勝手に消されるので一部「<」「>」は全角にしている.

広告
カテゴリー: 未分類 パーマリンク

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト /  変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト /  変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト /  変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト /  変更 )

%s と連携中