2012-07-18 32 views
0

我有兩個文件。 DOMAIN.txt文件包含某些領域一個awk腳本錯誤我無法修復

facebook.com 
google.com 
yahoo.com 

site.txt包含域下的一些網站,他們的URL數量。

music.google.com 2 
image.google.com 3 
music.facebook.com 8 
image.facebook.com 4 
map.yahoo.com 4 
new.yahoo.com 7 

我打算選擇這些網站,它的網址數大於其網域的平均網址數。例如,google.com的平均網址編號爲(2 + 3)/2=2.5,因此將挑選image.google.com

我寫awk腳本是這樣的:

BEGIN { 
     #read all domains into memory 
     while(getline dom < "./domain.txt" > 0){ 
       domain[dom]=0; 
     } 

     #count URLs number and sites number under each domain 
     for (dom in domain){ 
       sitenumber=0; 

       close("./site.txt") 
       while(getline < "./site.txt" >0){ 
         if(match($1,"."dom"$")){ 
           domain[dom]+=$2; 
           sitenumber++; 
           printf("%s\n",$0) >> "./sitesunderdomain"; 
         } 
       } 

       avgsitenumber = domain[dom]/sitenumber; 
       system("cat ./sitesunderdomain") #test output 

       close("./sitesunderdomain") 
       while(getline < "./sitesunderdomain" >0){ #loop A 
         print "why1" #test output 
         if($2>=avgsitenumber){ 
           print "why2" #testoutput 
           print $0,avgsitenumber>>"./result" 
         } 
       } 
       system("> ./sitesunderdomain") 
     }#for 
} 

然後我跑在猛砸awk腳本,得到輸出:

music.facebook.com 8 
image.facebook.com 4 
why1 
why2 
why1 
music.google.com 2 
image.google.com 3 
map.yahoo.com 4 
news.yahoo.com 7 

而且./result

music.facebook.com 8 6 

但正如我所料,輸出應該是

music.facebook.com 8 
image.facebook.com 4 
why1 
why2 
why1 
music.google.com 2 
image.google.com 3 
why1 
why2 
why1 
map.yahoo.com 4 
news.yahoo.com 7 
why1 
why2 
why1 

而且./result應該是:

music.facebook.com 8 6 
image.google.com 3 2.5 
news.yahoo.com 7 5.5 

好像在loop A位置,getline0domgoogle.comyahoo.com爲什麼?

+0

你可能想逃避比賽中的'.'。它符合任何角色。無論是「\」。「(除非需要是」\「。」')或'「[。]」';我會使用後者,因爲它不會引起有關要使用的反斜槓數量的尷尬問題。儘管如此,這與您的主要問題是切線的。 – 2012-07-18 16:07:52

+0

當試圖調試意外的輸出時,首先要做的就是回顯輸入 - 所以你可以確定你得到了你期望的結果。您可能還需要顯示您正在使用的數據文件;我記得從y'day的問題(​​我的時間;今天早些時候在UTC)的一般情況,但其他人不會提供這些信息。此外,您應該可以顯示您期望的輸出內容。另外,我不相信像這樣過濾出來的東西是很好的'awk'風格。使用數組來保存數據,而不是文件。 – 2012-07-18 16:12:30

+0

另請參見[如何在正則表達式中使用awk變量](http://stackoverflow.com/questions/11534173/how-to-use-awk-variables-in-regular-expressions/)。這是一個單獨的問題,但具有相同的一般背景。 – 2012-07-18 16:13:56

回答

2

你的代碼是一團糟。這不是與awk一起使用的方式。 Awk自動打開並逐行讀取您的文件,這不是使用getline的作業。這僅適用於特殊情況。

首先

close("./site.txt") 
while(getline < "./site-test" >0){ 

./site-test?您的文件是test.txt。它在我的測試中死亡。

:沒有必要創建文件時,你可以從RAM直接重複使用的數據,像數組。

:我不喜歡你的代碼在所有,但要解決這個問題,關閉與getline閱讀它和system("> ./sitesunderdomain")刪除,就像你之間./sitesunderdomain臨時文件:

## NOT here. 
##close("./sitesunderdomain") 

while(getline < "./sitesunderdomain" >0){ #loop A 
     print "why1" #test output 
     if($2>=avgsitenumber){ 
       print "why2" #testoutput 
       print $0,avgsitenumber>>"./result" 
     } 
} 

## Better here between the read and the write. 
close("./sitesunderdomain") 

system("> ./sitesunderdomain") 

現在運行腳本,如:

awk -f myscript.awk domain.txt site.txt 

,是否有輸出:

cat result 

有了結果如下:

music.facebook.com 8 6 
image.google.com 3 2.5 
new.yahoo.com 7 5.5 
1

我無法理解你的腳本。沒有必要手動打開這樣的文件; awk獨自處理它。如果你的代碼可以修復,我不是那麼做。

這就是我想出了替代:

#!/usr/bin/awk -f 

{ 
    domain=$1; sub(/^[a-z]*\./, "", domain); 
    mean[domain]=(mean[domain]*count[domain]+$2)/++count[domain]; 
    score[$1]=$2; 
} 

END { 
    printf("%7s\t%6s\t%s\n", "score", "mean", "domain"); 
    for (hostname in score) { 
    domain=hostname; sub(/^[a-z]*\./, "", domain); 
    if (score[hostname] > mean[domain]) { 
     printf("%6d\t%6.2f\t%s\n", score[hostname], mean[domain], hostname); 
    } 
    } 
} 

當我運行鍼對您的數據,我得到如下結果:

score mean domain 
    3 2.50 image.google.com 
    8 6.00 music.facebook.com 
    7 5.50 new.yahoo.com 

是輸出你期待?

+0

我喜歡你的單行「平均」計算。 :-) – Graham 2012-07-18 18:14:16

相關問題