一个我无法修复的awk脚本错误

一个我无法修复的awk脚本错误,awk,Awk,我有两个文件。 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的平均U

我有两个文件。 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
}
结果是

但正如我所预料的,输出应该是

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
结果应该是:

music.facebook.com  8  6
image.google.com  3  2.5
news.yahoo.com  7  5.5
在dom为google.com和yahoo.com时,getline返回0。
为什么?

你的代码乱七八糟。这不是与awk合作的方式。Awk会自动为您逐行打开和读取文件,使用getline并不是日常工作。这只适用于特殊情况

首先:

现在按如下方式运行脚本:

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

你的代码乱七八糟。这不是与awk合作的方式。Awk会自动为您逐行打开和读取文件,使用getline并不是日常工作。这只适用于特殊情况

首先:

现在按如下方式运行脚本:

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

我很难理解你的剧本。没有必要像那样手动打开文件;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

这是您期望的输出吗?

我无法理解您的脚本。没有必要像那样手动打开文件;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

这就是您所期望的输出吗?

您可能希望避开这个问题。在比赛中;它与任何角色都匹配。要么\。除非有必要。或[.];我会使用后者,因为它不会对要使用的反斜杠的数量提出令人尴尬的问题。不过,这与您的主要问题无关。当尝试调试意外输出时,第一步是回显输入,这样您就可以确保得到了预期的结果。您可能还需要显示正在使用的数据文件;我记得y'day的问题“我的时间”中的大背景;今天早些时候在UTC,但其他人将无法获得该信息。此外,您可能应该显示您期望的输出。另外,我不认为像那样将内容过滤到磁盘是好的awk风格。使用数组保存数据,而不是文件。另请参见。这是一个单独的问题,但具有相同的一般上下文。@JonathanLeffler:不是吗。建议有点刺耳?这个awk脚本已经走得太远了,你不觉得吗?@Graham:它非常糟糕,处理不当的元字符是它最不容易出现的问题之一。你可能会想逃避这个问题。在比赛中;它与任何角色都匹配。要么\。除非有必要。或[.];我会使用后者,因为它不会对要使用的反斜杠的数量提出令人尴尬的问题。不过,这与您的主要问题无关。当尝试调试意外输出时,第一步是回显输入,这样您就可以确保得到了预期的结果。您可能还需要显示正在使用的数据文件;我记得y'day的问题“我的时间”中的大背景;今天早些时候在UTC,但其他人将无法获得该信息。此外,您可能应该显示您期望的输出。另外,我不认为像那样将内容过滤到磁盘是好的awk风格。使用数组保存数据,而不是文件。另请参见。这是一个单独的问题,但具有相同的一般上下文。@JonathanLeffler:不是吗。建议有点刺耳?这个awk脚本已经走得太远了,你不觉得吗?@Graham:这很糟糕,错误处理的元字符是其中最小的问题之一。我喜欢你的一行平均计算:-我喜欢你的一行平均计算:-