数学的計算のために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

awk15の代わりに12を返します。数学計算を実行するために文字列をどのように入力しますかawk

答え1

expression_to_evaluateこれが機能している間にソースを制御しない限り、セキュリティ上のリスクがあるため、実行しないことをお勧めします。

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

答え2

awk文字列として提供される一般的な算術式を評価する方法はありません。 bc一方、シェルと同様に式を受け入れて評価します。

文字列を数学式として評価するには、awk式を次のように挿入する必要があります。パスワードプログラムに追加するawkか(潜在的にコード挿入の脆弱性を生成する)、評価したい表現タイプの独自のパーサーを作成します(これは一般的なコンピュータサイエンスの課題です)。

の値を整数に変換すると、文字列の空白文字まで変換できるため、コード12からこれを取得できます。これは文字列を整数に変換するときにCライブラリ関数がどのように機能するかであり、おそらく後で使用されるようです。awkexpression_to_evaluatestrtol()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 "$@"
}

混乱させて申し訳ありません!

オリジナル投稿

(注:この関数はファイルからインポートするか、awkスクリプトに入れる必要があります!上記を参照してください。)awkの関数は目的のeval()操作を実行します。これは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)}'

関連情報