값 열의 평균을 구하려고 할 때 정확한 숫자를 얻고 싶습니다.
예를 들어 다음은 입력 값 열입니다.
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
다음 awk 스크립트를 찾았습니다.단일 명령으로 숫자 목록의 최소값, 최대값, 중앙값 및 평균을 얻는 방법이 있습니까?. 숫자 데이터의 단일 열에 대한 합계, 개수, 평균, 중앙값, 최대값 및 최소값을 한 번에 가져옵니다. 표준 입력에서 읽고 탭으로 구분된 출력 열을 한 줄에 인쇄합니다. 조금 수정했습니다. 위의 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
소수점 이하 세 자리 숫자를 인쇄하는 것과 유사합니다 .
...| awk '{ sum+=$1} END { printf "%.3f\n", sum/NR }'
f
sum의 의미 g
와 정밀도 수정자( .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
1과 같은지, 즉 우리가 첫 번째 행에 있는지 확인합니다. ( ==
비교입니다. =
할당입니다.) 그렇다면 , 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
$
작은따옴표 또는 아포스트로피 문자는 ISO C에 대한 POSIX 확장입니다. 이는 부동 소수점 값의 정수 부분이나 정수 소수 값의 전체 부분에 천 단위 구분 기호가 포함되어야 함을 나타냅니다. 이는 해당 문자를 지원하는 로케일에서만 작동합니다. 예를 들어: