awkを使ってゼロ例外に分割する

awkを使ってゼロ例外に分割する

var1 = 6、var2 = 4変数に値を格納し、精度2で割って結果を変数に保存しようとしていますvar

var=`awk 'BEGIN {printf "%.2f\n", $var1/ $var2}'`

上記の作業を行うと awk: cmd. line:1: fatal: division by zero attempted

誰かが私がここで正確に見逃していることを指摘できますか?

ありがとうございます!

答え1

-v var=valueawkに変数を渡すために使用されます。

だから

awk -v var1="$var1" -v var2="$var2" 'BEGIN {printf "%.2f\n",var1/var2}'

与える

1.50

そして

var=$(awk -v var1="$var1" -v var2="$var2" 'BEGIN {printf "%.2f\n",var1/var2}') 

値を設定します。

あなたはする必要があります

  • -v var1="$var1"bashの$ var1をawkのvar1に変換する
  • var1以下で使用awk(必須ではない$, $var1var1=6 が$6値である)
  • echo入力を提供するawk(そうでなければ、awkは入力を待って中断されます)(awkでBEGINを忘れます)

答え2

$var1ここでとの内容を渡すことができます。$var2 シェルawk変数をスクリプトのパラメータとして使用し、特殊な配列変数を介してスクリプトからその変数にアクセスしますARGV

var=$(awk -- 'BEGIN {printf "%.2f", ARGV[1] / ARGV[2]}' "$var1" "$var")

または、変数をエクスポートしてシェルすることもできvar1ますvar2環境配列変数でawk検索するには、次の手順を実行します。ENVIRON

var=$(
  export var1 var2
  awk 'BEGIN {printf "%.2f", ENVIRON["var1"] / ENVIRON["var2"]}'
)

ARGV一般的な場合は、/ ENVIRONover-vまたは引数を使用して任意のデータを渡すことが一般的ですvar=value。後者はバックスラッシュ文字を破ることができるからです(もちろん数字には実際には問題にはなりませんが)。

コードパラメータにシェル変数拡張を含めると、awkコード注入の脆弱性が発生するため、回避する必要があります。以下にも適用されます。パラメータにパラメータ拡張を引用することを忘れました。-v

シェルがまたは次の場合、これはksh93まったく必要ありませんzshawk

printf -v var %.2f '1.*var1 / var2' # zsh
var=${ printf %.2f '1.*var1 / var2'; } # ksh93

(AND を乗算すると、1.計算は浮動小数点形式で実行されます.)

しかし、あなたが必要であることに注意してください。この変数の内容を整理してください。そうしないと、別のランダムコード実行の脆弱性になります。これらの変数の内容があなたの管理下にない場合。

答え3

これは単純なスクリプトには問題がありますが、実際に使用したい場合はawkより複雑なスクリプトには適しています。これには2つの方法で解決できます。

  1. 単純な引用符を二重引用符に置き換えます。ドルの拡大を防ぐ簡単な方法。これにより、既存の二重引用符をエスケープする必要性などの他の問題が発生し、フィールドawk内でフィールドを使用したい場合も同じ要件が発生します。

    var=`awk "BEGIN {printf \"%.2f\n\", $var1/ $var2}"`
    
  2. 変数をawk正しい方法で渡します。

    var=$(awk -v var1="$var1" var2="$var2" 'BEGIN {printf("%`.2f\n",var1,var2)}')
    

関連情報