我试图在文件中找到几个数字的平均值,其中包含"<整体>"在线。
我的代码:
awk -v file=$file '{if ($1~"<Overall>") {rating+=$1; count++;}} {rating=rating/count; print file, rating;}}' $file | sed 's/<Overall>//'
我正在
awk: cmd. line:1: (FILENAME=[file] FNR=1) fatal: division by zero attempted
为每个文件。如果文件确实包含诸如&#34;&lt;&lt;总体而言&gt; 5&#34;
编辑: 根据要求从(非常大)输入文件中取样:
<Author>RW53
<Content>Location! Location? view from room of nearby freeway
<Date>Dec 26, 2008
<No. Reader>-1
<No. Helpful>-1
<Overall>3
<Value>4
<Rooms>3
<Location>2
<Cleanliness>4
<Check in / front desk>3
<Service>-1
<Business service>-1
预期产出:
[filename] X
其中X是包含&lt;的所有行的平均值。总体而言&gt;
答案 0 :(得分:4)
使用Awk
,如下所示
awk -F'<Overall>' 'NF==2 {sum+=$2; count++}
END{printf "[%s] %s\n",FILENAME,(count?sum/count:0)}' file
对于包含这样的两个<Overall>
子句的输入文件,它会生成如下结果,文件名为input-file
<Author>RW53
<Content>Location! Location? view from room of nearby freeway
<Date>Dec 26, 2008
<No. Reader>-1
<No. Helpful>-1
<Overall>3
<Value>4
<Rooms>3
<Location>2
<Cleanliness>4
<Check in / front desk>3
<Service>-1
<Business service>-1
<Overall>2
运行它会产生,
[input-file] 2.5
部分-F'<Overall>'
将带有限制器的输入行拆分为<Overall>
,基本上只有具有<Overall>
的行和其后的数字将被过滤,数字为{{ 1}}总结并存储在$2
变量中,并在sum
中跟踪计数。
在打印完所有行之后执行c
子句,它基本上使用END
特殊变量awk
打印文件名,该变量保留已处理文件的名称并计算平均值< em> iff 计数不为零。
答案 1 :(得分:1)
在完全阅读文件以计算平均评分之前,您不会等待。如果您使用模式而不是if
语句,这会更简单。您还需要在尝试增加<Overall>
之前删除rating
。
awk '$1 ~ /<Overall>/ {rating+=sub("<Overall>", "", $1); count++;}
END {rating=rating/(count?count:1); print FILENAME, rating;}' "$file"
(已更新答案以修正sub
调用中的拼写错误并正确避免除以0.。
答案 2 :(得分:0)
awk -F '>' '
# separator of field if the >
# for line that containt <Overall>
/<Overall>/ {
# evaluate the sum and increment counter
Rate+=$2;Count++}
# at end of the current file
END{
# print the average.
printf( "[%s] %f\n", FILENAME, Rate / ( Count + ( ! Count ) )
}
' ${File}
# one liner
awk -F '>' '/<Overall>/{r+=$2;c++}END{printf("[%s] %f\n",FILENAME,r/(c+(!c))}' ${File}
注意:
( c + ( ! c ) )
使用逻辑NOT(!
)的副作用。如果c = 0,则值为1,否则为0。因此,如果c = 0,则添加1,如果不是,则将0添加到自身,保持至少为1的除法值。