
ファイル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」で始まるレコードの4番目のフィールドから合計金額の合計を取得する必要があります。すべての行の合計を変数に保存したいと思います。合計したら、すべての小数点を正しくキャプチャする必要があります。 「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}'
2つのサンプルファイルを提供してください
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.00878
15ビット幅のため)。
答え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
精度を抽出するより良い方法があるかもしれません。正規表現の一致が最初に浮かび上がるのです。