2015-01-09 38 views
0
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文件中的輸入(百萬行的樣本)。 我想根據日期總結持續時間。 我關心的是我要總結第一百萬行 我使用的awk程序是:使用awk從一個大文件中的行「A」到行「B」的總和

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> 1 & & NR < = 1000000

任何建議?請!

+0

'NR> 1 && NR <= 1000000 FNR == 1'您錯過了';'之間的那些假設是兩個測試。 NR> 1 && NR <= 1000000; FNR == 1'你想要什麼條件控制?帶有'sub'的塊? – 2015-01-09 18:27:50

+0

哇!我收回了從第1行到1000000的所有數據,除了同樣的過去結果之外,還先打印 – Baodbao 2015-01-09 18:35:07

+1

嘗試:'NR == 1 {next} NR> 1000000 {exit}' – 2015-01-09 18:35:35

回答

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] 
    } 
} 

很多誤區成爲正確的縮進明顯。

你看到百萬行的原因是由於這樣的:

NR>1 && NR<=1000000 

也就是說,沒有動作塊的條件。如果條件爲真,則默認操作是打印當前記錄。這就是爲什麼你看到很多awk單行尾以1

+0

感謝您的回答@glennjackman!這正是我所期待的。我想問一些問題,您是否認爲在返回結果之前腳本會讀取所有行(讀取輸入文件的所有行),或者一旦它到達第1,000,000行,將顯示結果? – Baodbao 2015-01-09 19:38:53

+0

直到END塊纔開始打印。在讀取所有輸入之前,awk不會進入END塊。如果您想要跳過1,000,000後的所有行,請添加'NR> 1000000 {exit}' – 2015-01-09 20:50:24

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 

而不是拋棄你的標題行,它使用它的是持續時間爲場4創建一個字段名映射到它們中的每一行順序,以便而不必硬編碼的數組f[] (或其他),你只需將其引用爲$(f["duration"])

任何時候你的輸入文件都有一個標題行,不要放棄它 - 使用它,這樣你的腳本就不會和輸入文件中字段的順序相關聯。

相關問題