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
我找到了以下單行 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
我從Is there a way to get the min, max, median, and average of a numbers in a single command? 中找到了以下 awk 腳本?. 它將一次性獲得單列數字數據的總和、計數、平均值、中值、最大值和最小值。它從標準輸入讀取,並在一行上列印輸出的製表符分隔列。我稍微調整了一下。我注意到它不需要
NR == 1
與上面的 awk 命令不同(在我的第一次編輯中)。有人可以解釋為什麼嗎?我認為這與數字數據已被排序並放入數組的事實有關。#!/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]} } '
... | awk '{ sum+=$1} END { print sum/NR}'
預設情況下,(GNU) awk 列印最多 6 個有效數字(加上指數部分)的數字。這來自變數的
OFMT
預設值。它並沒有在文件中這麼說,但這僅適用於非整數值。您可以更改
OFMT
以影響所有printf
在此處使用,因此如果平均值恰好是整數,它也可以工作。類似的東西%.3f
會列印小數點後三位數字。...| awk '{ sum+=$1} END { printf "%.3f\n", sum/NR }'
請參閱文件以了解
f
andg
和精度修飾符的含義(.prec
在第二個連結中):
- https://www.gnu.org/software/gawk/manual/html_node/Control-Letters.html
- https://www.gnu.org/software/gawk/manual/html_node/Format-Modifiers.html
awk 'NR == 1 { max=$1; min=$1; sum=0 } ...'
這不會初始化
NR
. 相反,它檢查是否NR
等於一,即我們在第一行。(==
是比較,=
是賦值。) 如果是,則初始化max
和。沒有它,就會從零開始。你永遠不可能有一個負的最大值或一個正的最小值。min``sum``max``min