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

최대값, 최소값 및 평균값을 얻기 위해 다음 한 줄 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 }'

fsum의 의미 g와 정밀도 수정자( .prec두 번째 링크)에 대한 설명서를 참조하세요.

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

초기화되지 않습니다 NR. 대신, 그것이 NR1과 같은지, 즉 우리가 첫 번째 행에 있는지 확인합니다. ( ==비교입니다. =할당입니다.) 그렇다면 , maxmin을 초기화합니다 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 확장입니다. 이는 부동 소수점 값의 정수 부분이나 정수 소수 값의 전체 부분에 천 단위 구분 기호가 포함되어야 함을 나타냅니다. 이는 해당 문자를 지원하는 로케일에서만 작동합니다. 예를 들어:

관련 정보