0

2つのファイルがあります。 domain.txtにはいくつかのドメインが含まれています

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

ドメインの平均URL番号よりも大きいURL番号のサイトを選択します。たとえば、google.comの平均URL番号は(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
}

次に、bashで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位置にあるようです、google.comyahoo.comだったときにgetline戻ります。 なんで?0dom

4

2 に答える 2

2

あなたのコードはめちゃくちゃです。それはで作業する方法ではありませんawkAwk自動的に開いてファイルを1行ずつ読み取ります。これは、を使用したjourジョブではありませんgetline。これは特別な場合のみです。

まず第一に:

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

./site-test?あなたのファイルはtest.txtです。それは私のテストで死にました。

2番目:配列のようにRAMから直接データを再利用できる場合は、ファイルを作成する必要はありません。

3番目:私はあなたのコードがまったく好きではありませんが、それを修正するには、次のように、コードを読んでから削除する./sitesunderdomainまでの間に一時ファイルを閉じます。getlinesystem("> ./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
于 2012-07-18T17:01:59.773 に答える
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

それはあなたが期待している出力ですか?

于 2012-07-18T17:09:18.850 に答える