文件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"
printf 使用 arg 作为 %f 的精度。
可以计算精度。
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.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
可能有更好的方法来提取精度 - 正则表达式匹配只是我首先想到的。