awkの数値形式と丸めの問題

awkの数値形式と丸めの問題

値列の平均を求めようとすると、正確な数値を取得したいと思います。

たとえば、次は入力値の列です。

1426044
1425486
1439480
1423677
1383676
1360088
1390745
1435123
1422970
1394461
1325896
1251248
1206005
1217057
1168298
1153022
1199310
1250162
1247917
1206836

次のコマンドを使用する場合:

... | awk '{ sum+=$1} END { print sum/NR}'

私は次のような結果を得ます1.31638e+06。しかし、私はこの形式の正確な数が欲しいです。1316375.05または、より良い結果を得る。 1,316,375.05

コマンドラインツールのみを使用してこれを行うにはどうすればよいですか?

編集1

最大値、最小値、平均値を取得するために、次の1行のawkコマンドを見つけました。

awk 'NR == 1 { max=$1; min=$1; sum=0 } { if ($1>max) max=$1; if ($1<min) min=$1; sum+=$1;} END {printf "Min: %d\tMax: %d\tAverage: %.2f\n", min, max, sum/NR}'

NRを1に初期化する必要があるのはなぜですか?を削除すると、NR == 1誤った結果が表示されます。

編集2

次のawkスクリプトが見つかりました。単一のコマンドで数値リストの最小値、最大値、中央値、平均を取得する方法はありますか?。数値データの単一列の合計、数、平均、中央値、最大値、最小値を一度に取得します。標準入力から読み込み、タブ区切りの出力列を1行に印刷します。少し修正しました。上記のawkコマンドと異なる必要はないことがわかりましたNR == 1(最初の編集で)。誰かが理由を説明できますか?これは、数値データがソートされて配列に格納されるという事実に関連していると思います。

#!/bin/sh

sort -n | awk '

  $1 ~ /^(\-)?[0-9]*(\.[0-9]*)?$/ {
    a[c++] = $1;
    sum += $1;
  }
  END {
    ave = sum / c;
    if( (c % 2) == 1 ) {
      median = a[ int(c/2) ];
    } else {
      median = ( a[c/2] + a[c/2-1] ) / 2;
    }

    {printf "Sum: %d\tCount: %d\tAverage: %.2f\tMedian: %d\tMin: %d\tMax: %d\n", sum, c, ave, median, a[0], a[c-1]}
  }
'

答え1

... | awk '{ sum+=$1} END { print sum/NR}'

デフォルトでは、(GNU)awkは最大6桁の有効数字(指数を含む)を印刷します。これはデフォルト値に由来します。OFMT変数。ドキュメントにはあまり記載されていませんが、これは整数値ではなく数値にのみ機能します。

OFMTすべてのprint文に影響を与えるように変更するか、printfここで使用できるため、平均が整数の場合に機能します。%.3f小数点以下の3桁の数字を印刷するのと似ています。

...| awk '{ sum+=$1} END { printf "%.3f\n", sum/NR }'

fsumの意味gと精度修飾子(.prec2番目のリンク)のドキュメントを参照してください。

awk 'NR == 1 { max=$1; min=$1; sum=0 } ...'

初期化されませんNR。代わりに、それがNR1に等しいかどうか、つまり私たちが最初の行にあることを確認します。 (==比較です。=割り当てです。)そうであれば、maxおよびminを初期化しますsum。それがなければ、最初から始めるmaxでしょうmin。負の最大値または正の最小値を持つことはできません。

答え2

GNUを使用している場合は、awkこれを試してください。修飾子を使用してコンマを追加します'

$ awk '{sum+=$1}END{printf "%'\''.2f\n",sum/NR}' filename
1,316,375.05
$

お持ちの方はjqこれをお試しください。

$ jq -s min,max,add/length filename
1153022
1439480
1316375.05
$

~からgnu.org:gawk型修飾子

一重引用符またはアポストロフィ文字は、ISO CのPOSIX拡張です。これは、浮動小数点値の整数部分または整数小数値の全部分に千単位の区切り文字を含める必要があることを示します。これは、その文字をサポートするロケールでのみ機能します。たとえば、

関連情報