一个我无法修复的awk脚本错误
我有两个文件。 domain.txt包含一些域一个我无法修复的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
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:这很糟糕,错误处理的元字符是其中最小的问题之一。我喜欢你的一行平均计算:-我喜欢你的一行平均计算:-