2016-06-07 67 views
3

我有數百個文件要處理。每個文件都包含數百萬行。大文件awk和sum rows

示例文件內容:

--------------- 
12 
3 
5 
--------------- 
8 
0 
5 
--------------- 
1 
5 
56 
4 
--------------- 

我需要(從以前的文件破折號分隔的數字之和),它看起來像下面的輸出:

20 
13 
66 

我用whileifelse結合awk,但if/else大大減緩處理。

任何想法如何使用純awk加快計算?

+0

你應該顯示你的代碼 - 在shell腳本或'awk'腳本中是'while'和'if'嗎?無論如何,'awk'腳本中不需要循環或'if'條件。一個文件可以沒有最後一行破折號? –

+1

wrt'我用while,if,else' - 讀[爲什麼要使用shell循環處理文本被認爲是壞行爲](http://unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice)和一個shell教程。另外請參閱Arnold Robbins編寫的「有效的Awk編程」第4版。 –

+0

示例文件內容是否代表_single_或_multiple_文件? – mklement0

回答

3

你不需要的if/else塊,

$ awk 'FNR>1 && /^----/ {print sum; sum=0; next} {sum+=$1}' file{1,2} 
20 
13 
66 
20 
13 
66 

例如您輸入文件1和文件2的副本。也許你會一次運行一個或多個輸入一個前綴的前綴,例如

$ awk 'FNR==1{block=0} FNR>1 && /^----/ {print FILENAME, ++block, sum; sum=0; next} 
             {sum+=$1}' file{1,2} 

file1 1 20 
file1 2 13 
file1 3 66 
file2 1 20 
file2 2 13 
file2 3 66 
+2

絕對是'搶救'時刻!祝你們好運。 – shellter

+1

對於這個問題,這些挑剔不是直接相關的,但對現實世界而言,它們可能是。如果最後一個文件不以破折號行結束,則不會輸出最後一個和。這是一個麻煩解決。如果一個文件沒有以破折號行結束,並且下一個文件沒有以破折號行開始,那麼可以合併這兩個和。將第一行的破折線添加到「sum」似乎有點有趣 - 儘管「awk」將它視爲零。但是對於格式良好的投入,這很好。 –

2

另一種方法。我很好奇它如何加快速度明智

awk -v RS='\n-+\n' -F'\n' 'NF {s=0; for(i=1; i<=NF; i++) s+=$i; print s}' file ... 
+1

由於多字符RS,您應該提及它是特定於gawk的。 –

3
$ awk '/^-+$/{if (s!="") print s; s=""; next} {s+=$0}' file 
20 
13 
66 

註釋來""設定/比較,如果是VS只是初始化爲空字符串爲零的累計值不同的方式處理它吧。

-1

感謝大家花時間幫助我! awk的例子比起while/if條件來說非常快。感謝鏈接也描述了原因。看來我創建的代碼中最糟糕的版本,我可以這樣寫: -/

我的代碼版本,它的作品,以及,但它明顯變慢:

sum=0 
while read line 
       do 
       if [ "$line" = "---------------" ]; then 
         echo $sum 
         sum=0 
       else sum=`echo $line $sum | awk '{print $1 + $2}'` 
       fi 
done < input_file.txt 

再次感謝大師!

+0

它不僅速度慢,而且會給出不同的輸入值和/或環境設置和/或目錄中的內容。不要在任何重要的事情上運行它。相反,選擇你給予的解決方案之一,並做到這一點。你還問過任何想法如何使用純awk來加速計算?所以有一個當之無愧的downvote發佈你自己的解決方案,甚至沒有做你所要求的! –