파일 1:

파일 1:

파일 1:

H|~^20200425|~^abcd|~^sum
R|~^abc|~^2019-03-06T12:33:52.27|~^1000123.34567|~^2018-04-12T12:33:52.27|
R|~^abc|~^2019-03-05T12:33:52.27|~^111930.02876|~^2018-10-23T12:33:52.27|
R|~^abc|~^2019-03-05T12:33:52.27|~^2112320.028|~^2018-10-24T12:33:52.27|
R|~^abc|~^2019-03-06T12:33:52.27|~^12230.0809|~^2018-09-11T12:33:52.27|
R|~^abc|~^2019-03-05T12:33:52.27|~^3076543789.00878|~^2018-08-05T12:33:52.27|
R|~^abc|~^2019-03-06T12:33:52.27|~^156655.0389|~^2018-10-23T12:33:52.27|
R|~^abc|~^2019-03-06T12:33:52.27|~^10453.0489|~^2018-04-08T12:33:52.27|
R|~^abc|~^2019-03-05T12:33:52.27|~^20654.0907|~^2018-07-23T12:33:52.27|
T|~^20200425|~^abcd|~^3424365.66183

파일 2:

H|~^20200426|~^abcd|~^sum
R|~^abc|~^2019-03-07T12:33:52.27|~^10.347|~^2018-04-12T12:33:52.27|
R|~^abc|~^2019-03-08T12:33:52.27|~^111.06|~^2018-10-23T12:33:52.27|
R|~^abc|~^2019-03-05T12:33:52.27|~^2112.08|~^2018-10-24T12:33:52.27|
R|~^abc|~^2019-03-06T12:33:52.27|~^12230.089|~^2018-09-11T12:33:52.27|
R|~^abc|~^2019-03-04T12:33:52.27|~^30769.078|~^2018-08-05T12:33:52.27|
R|~^abc|~^2019-03-06T12:33:52.27|~^155.09|~^2018-10-23T12:33:52.27|
R|~^abc|~^2019-03-03T12:33:52.27|~^10.89|~^2018-04-08T12:33:52.27|
R|~^abc|~^2019-03-05T12:33:52.27|~^206.07|~^2018-07-23T12:33:52.27|
T|~^20200426|~^abcd|~^155604.704

"R"로 시작하는 레코드의 네 번째 필드에서 총 금액의 합계를 구해야 합니다. 모든 행의 합계를 변수에 저장하고 싶습니다. 합산 후에는 모든 소수점을 올바르게 캡처해야 합니다. "T"로 시작하는 예고편 레코드는 참조용으로 마지막 필드에 합계 출력이 있습니다.

답변1

분리기는 도전이다

나는 그것을 알아

awk -F '[|^]' '$1 == "R" { s+=$7 ; } $1 == "T" {  printf "Sum %.5f\n",s}'

주다

Sum 3079968154.67061

어디

  • -F '[|^]'|또는 ^필드 구분 기호로 사용하도록 awk에 지시
  • $1 == "R" { s+=$7 ; }s첫 번째 필드가 다음인 경우 7번째 필드의 합계R
  • $1 == "T" { printf "Sum %.5f\n",s}5자리를 포함한 합계를 인쇄하세요.

조정산출정밀도, 신비한 printf(3) 옵션을 사용할 수 있습니다

awk -v prec=3 -F '[|^]' '$1 == "R" { s+=$7 ; } 
     $1 == "T" { print ; printf "Sum %.*f\n",prec,s}' 

주다

Sum 3079968154.671

어디

  • -v prec=3정확성을 제공
  • *"Sum %.*f\n"%f의 정밀도로 arg를 사용하도록 printf에 지시합니다 .

정확도를 계산할 수 있습니다.

awk  -F '[|^]' '$1 == "R" { s+=$7 ; } 
                $1 == "T" { print ; 
                            prec=length($7)-index($7,".");  
                            printf "t:%s, Sum %.*f\n",$7,prec,s}'

두 개의 예제 파일을 제공하십시오

T|~^20200425|~^abcd|~^3424365.66183
t:3424365.66183, Sum 3079968154.67061

T|~^20200426|~^abcd|~^155604.704
t:155604.704, Sum 45604.704

음수 정밀도(prec=-2에서 수백으로 반올림)에서는 작동하지 않습니다.

정확성에 대한 참고사항:

~에 따르면https://en.wikipedia.org/wiki/Double-precision_floating-point_format정밀도는 52비트, 즉 약 15자리입니다. 위의 숫자는 아마도 정확한 합계의 근사치일 것입니다( 3076543789.0087815비트 너비로 인해).

답변2

통과되면

모든 소수점을 올바르게 캡처합니다.

모든 용어에 대해 최대 정밀도로 합계를 인쇄하려는 경우 정밀도를 추적해야 할 수도 있습니다. 예를 들면 다음과 같습니다.

$ awk -F'\\|~\\^' '
    $1=="R"{sum+=$4; if(match($4,/\.[0-9]+/) && RLENGTH-1>p) {p=RLENGTH-1}} 
    END{printf "%.*f\n",p,sum}
  ' File2
  45604.704

$ awk -F'\\|~\\^' '
    $1=="R"{sum+=$4; if(match($4,/\.[0-9]+/) && RLENGTH-1>p) {p=RLENGTH-1}} 
    END{printf "%.*f\n",p,sum}
  ' File1
  3079968154.67061

정밀도를 추출하는 더 좋은 방법이 있을 수 있습니다. 정규식 일치가 가장 먼저 떠오르는 것입니다.

관련 정보