aNumber|bNumber|startDate|timeZone|duration|currencyType|cost|
22677512549|778|2014-07-02 10:16:35.000|NULL|NULL|localCurrency|0.00|
22675557361|76457227|2014-07-02 10:16:38.000|NULL|NULL|localCurrency|10.00|
22677521277|778|2014-07-02 10:16:42.000|NULL|NULL|localCurrency|0.00|
22676099496|77250331|2014-07-02 10:16:42.000|NULL|NULL|localCurrency|1.00|
22667222160|22667262389|2014-07-02 10:16:43.000|NULL|NULL|localCurrency|10.00|
22665799922|70110055|2014-07-02 10:16:45.000|NULL|NULL|localCurrency|20.00|
22676239633|433|2014-07-02 10:16:48.000|NULL|NULL|localCurrency|0.00|
22677277255|76919167|2014-07-02 10:16:51.000|NULL|NULL|localCurrency|1.00|
这是我在csv文件中的输入(百万行的样本)。 我想根据日期总结持续时间。 我担心的是我想先总结100万行 我正在使用的awk程序是:
test.awk
BEGIN { FS = "|" }
NR>1 && NR<=1000000
FNR == 1{ next }
{
sub(/ .*/,"",$3)
key=sprintf("%10s",$3)
duration[key] += $5 } END {
printf "%-10s %16s,"dAccused","Duration"
for (i in duration) {
printf "%-4s %16.2f i,duration[i]
}}
我运行我的脚本
$awk -f test.awk 'file'
我的输入并没有考虑我的条件NR&gt; 1&amp;&amp; NR&LT; = 1000000
有什么建议吗?请!
答案 0 :(得分:3)
您正在寻找:
BEGIN { FS = "|" }
1 < NR && NR <= 1000000 {
sub(/ .*/, "", $3)
key = sprintf("%10s",$3)
duration[key] += $5
}
END {
printf "%-10s %16s\n", "dAccused", "Duration"
for (i in duration) {
printf "%-4s %16.2f i,duration[i]
}
}
通过适当的缩进,很多错误都会变得很明显。
您看到1,000,000行的原因是:
NR>1 && NR<=1000000
这是一个没有动作块的条件。默认操作是在条件为真时打印当前记录。这就是为什么你看到很多awk单行以数字1
答案 1 :(得分:1)
您没有发布任何预期的输出,并且您的持续时间字段始终为NULL,因此仍然不清楚您真正想要的输出,但这可能是正确的方法:
$ cat tst.awk
BEGIN { FS = "|" }
NR==1 { for (i=1;i<NF;i++) f[$i] = i; next }
{
sub(/ .*/,"",$(f["startDate"]))
sum[$(f["startDate"])] += $(f["duration"])
}
NR==1000000 { exit }
END { for (date in sum) print date, sum[date] }
$ awk -f tst.awk file
2014-07-02 0
它不是丢弃标题行,而是使用它来创建一个数组f[]
,它将字段名称映射到每行中的顺序,因此不必硬编码该字段的持续时间是字段4(或其他)您只需将其引用为$(f["duration"])
。
如果您的输入文件有标题行,请不要丢弃它 - 请使用它,这样您的脚本就不会与输入文件中的字段顺序相关联。