Awk 从日期-时间-更改中提取日期。到,并打印不同字段的汇总
这是我掌握的数据样本。每次更改日期时,我都要汇总Awk 从日期-时间-更改中提取日期。到,并打印不同字段的汇总,awk,Awk,这是我掌握的数据样本。每次更改日期时,我都要汇总成本,余额后,主要金额和余额前,但我担心的是,我的日期与时间组合在一起,小数点分隔符是点而不是逗号,因此我的awk脚本无法执行该操作。 我可以有一个AWK脚本,它首先只提取日期,所以最后我会有一个输出,如下所示: aNumber bNumber startDate cost balanceAfter trafficCase Operator unknown3 MainAmount BALANCEBEFORE 22676
成本
,余额后
,主要金额
和余额前
,但我担心的是,我的日期与时间组合在一起,小数点分隔符是点而不是逗号,因此我的awk脚本无法执行该操作。
我可以有一个AWK脚本,它首先只提取日期,所以最后我会有一个输出,如下所示:
aNumber bNumber startDate cost balanceAfter trafficCase Operator unknown3 MainAmount BALANCEBEFORE
22676239633 433 2014-07-02 10:16:48.000 0,00 0.20 0 Short Code 397224944 0.0000 0.2000
22677277255 76919167 2014-07-02 10:16:51.000 1,00 92.60 0 Airtel 126268625 0.0000 92.6000
22676777508 76701575 2014-07-02 10:16:55.000 1,00 217.00 0 Airtel 4132186103 0.0000 217.0000
22665706841 433 2014-07-02 10:16:57.000 0,00 69.50 0 Short Code 4133821554 0.0000 69.5000
22665799922 70110055 2014-07-03 10:16:45.000 20,00 0.50 0 Telmob 126260244 20.0000 0.5000
22676239633 433 2014-07-03 10:16:48.000 0,00 0.20 0 Short Code 397224944 0.0000 0.2000
22677277255 76919167 2014-07-04 10:16:51.000 1,00 92.60 0 Airtel 126268625 0.0000 92.6000
22676777508 76701575 2014-07-04 10:16:55.000 1,00 217.00 0 Airtel 4132186103 0.0000 217.0000
22665706841 433 2014-07-05 10:16:57.000 0,00 69.50 0 Short Code 4133821554 0.0000 69.5000
这是我的AWK脚本
Date Cost balanceAfter MainAmount BALANCEBEFORE
02/07/2014 2,00 379,3 0 379,3
03/07/2014 20,00 0,7 20 0,7
04/07/2014 2,00 309,6 0 309,6
05/07/2014 0,00 69,5 0 69,5
编辑:根据Etan Reisner的建议,避免预处理步骤,使用
$NF
处理运算符
列中不同数量的令牌
awk -F 'NR==1 {header=$0; next} {a[$3]+=$4 a[$3]+=$5 a[$3]+=$9 a[$3]+=$10} END {for (i in a) {printf "%d\t%d\n", i, a[i]}; tot+=a[i]};' out.txt>output.doc
这不需要对文件进行预处理:
$ cat data.txt
aNumber bNumber startDate cost balanceAfter trafficCase Operator unknown3 MainAmount BALANCEBEFORE
22676239633 433 2014-07-02 10:16:48.000 0,00 0.20 0 Short Code 397224944 0.0000 0.2000
22677277255 76919167 2014-07-02 10:16:51.000 1,00 92.60 0 Airtel 126268625 0.0000 92.6000
22676777508 76701575 2014-07-02 10:16:55.000 1,00 217.00 0 Airtel 4132186103 0.0000 217.0000
22665706841 433 2014-07-02 10:16:57.000 0,00 69.50 0 Short Code 4133821554 0.0000 69.5000
22665799922 70110055 2014-07-03 10:16:45.000 20,00 0.50 0 Telmob 126260244 20.0000 0.5000
22676239633 433 2014-07-03 10:16:48.000 0,00 0.20 0 Short Code 397224944 0.0000 0.2000
22677277255 76919167 2014-07-04 10:16:51.000 1,00 92.60 0 Airtel 126268625 0.0000 92.6000
22676777508 76701575 2014-07-04 10:16:55.000 1,00 217.00 0 Airtel 4132186103 0.0000 217.0000
22665706841 433 2014-07-05 10:16:57.000 0,00 69.50 0 Short Code 4133821554 0.0000 69.5000
$ cat so2.awk
NR > 1 {
cost = $5;
balanceAfter = $6;
mainAmount = $(NF - 1);
balanceBefore = $NF;
sub(",", ".", cost);
sub(",", ".", balanceAfter);
sub(",", ".", mainAmount);
sub(",", ".", balanceBefore);
dateCost[$3] += cost;
dateBalanceAfter[$3] += balanceAfter;
dateMainAmount[$3] += mainAmount;
dateBalanceBefore[$3] += balanceBefore;
}
END {
printf("%s\t%s\t%s\t%s\t%s\n", "Date", "Cost", "BalanceAfter", "MainAmount", "BalanceBefore");
for (i in dateCost) {
printf("%s\t%f\t%f\t%f\t%f\n", i, dateCost[i], dateBalanceAfter[i], dateMainAmount[i], dateBalanceBefore[i]);
}
}
$ awk -f so2.awk data.txt
Date Cost BalanceAfter MainAmount BalanceBefore
2014-07-02 2.000000 379.300000 0.000000 379.300000
2014-07-03 20.000000 0.700000 20.000000 0.700000
2014-07-04 2.000000 309.600000 0.000000 309.600000
2014-07-05 0.000000 69.500000 0.000000 69.500000
根据您的输入,类似于
sed's/,/\./g'| awk[您的实际脚本]>output.txt的输入应该可以做到这一点,如果您不想在数值中使用逗号而不是点,您可以使用反向正则表达式再次将日期和时间作为两个单独的字段传送到sed。请注意,awk将日期和时间视为两个单独的字段,这将使您的成本为5美元(而不是4美元),余额在$6(而不是$5)之后,等等。另一个问题是操作员列,Short code
这样的值是两个字段,而Airtel
是一个字段。如果你的文件是标签分开的,事情就变得容易多了。尽管我在考虑你所说的,它仍然返回0作为成本总和的值-@jas“Short code”和“Airtel”似乎只在一个单独的区域@jas,你可以直接在awk中进行修复(然后强制awk用$0=$0重新拆分)但是您也不需要这样做,因为您可以只使用mainmount=$(NF-1);余额前=$NF代码>在脚本中。(还有成本是列$5
和余额之后是列$6
,而且输出看起来不是来自脚本%s
就我所知不会用那样的零填充。)感谢@EtanReisner,我修复了代码以匹配我最后实际运行的代码。关于使用$NF和$(NF-1)来解决数据问题,这一点非常好!出于某种原因,我的printf没有%f的默认格式awk'BEGIN{printf(“%f\n”,3.14)}
给我3.140000
是的,%f
这样做<代码>%s
没有<代码>%f
用于浮点数。谢谢@jas。代码是正确的,但我有数百万行,所以有没有办法将所有任务合并到一个代码中?是的,@Baodbao,请参阅更新的答案,其中包含了Etan Reisner的建议,以避免额外的步骤。谢谢Glenn!它工作正常,但存在一个问题。您的脚本规定输入必须进行良好的“分类”。我的意思是,在2014-07-03前后都有2014-07-02,脚本将返回我作为输出*2014-07-02*2014-07-03*2014-07-02,而不是唯一的2014-07-02和2014-07-03,这是真的。如果你的数据真的是这样,用jas的答案来代替:它是正确的。
awk '
BEGIN {print "Date Cost BalanceAfter MainAmount BalanceBefore"}
NR == 1 {next}
function showday() {
printf "%s\t%.2f\t%.1f\t%d\t%.1f\n", date, cost, bAfter, main, bBefore
}
date != $3 {
if (date) showday()
date = $3
cost = bAfter = main = bBefore = 0
}
{
sub(/,/, ".", $5)
cost += $5
bAfter += $6
main += $(NF-1)
bBefore += $NF
}
END {showday()}
' file | column -t
Date Cost BalanceAfter MainAmount BalanceBefore
2014-07-02 2.00 379.3 0 379.3
2014-07-03 20.00 0.7 20 0.7
2014-07-04 2.00 309.6 0 309.6
2014-07-05 0.00 69.5 0 69.5