致命:试图找到均值时尝试除以零?
fatal: division by zero attempted when trying to find mean?
我正在尝试求一个文件中几个数字的平均值,其中包含“<总体>”这一行。
我的代码:
awk -v file=$file '{if (~"<Overall>") {rating+=; count++;}} {rating=rating/count; print file, rating;}}' $file | sed 's/<Overall>//'
我得到
awk: cmd. line:1: (FILENAME=[file] FNR=1) fatal: division by zero attempted
对于每个文件。如果文件确实包含诸如“< Overall >5”
之类的行,我不明白为什么计数会为零
编辑:
根据要求,来自(非常大的)输入文件的样本:
<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 是包含 的所有行的平均值
使用如下 Awk
,
awk -F'<Overall>' 'NF==2 {sum+=; 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>
和后面的行会被过滤,数字是</code> 汇总并存储在 <code>sum
变量中,计数在 c
.
中跟踪
END
子句在打印完所有行后执行,这基本上使用 awk
特殊变量 FILENAME
打印文件名,该变量保留已处理文件的名称,平均值为计算 iff 计数不为零。
您无需等到完全阅读文件后才计算平均评分。如果您使用模式而不是 if
语句,这会更简单。您还需要在 尝试增加 rating
.
之前删除 <Overall>
awk ' ~ /<Overall>/ {rating+=sub("<Overall>", "", ); count++;}
END {rating=rating/(count?count:1); print FILENAME, rating;}' "$file"
(答案已更新以修复调用 sub
时的拼写错误并正确避免除以 0。)
awk -F '>' '
# separator of field if the >
# for line that containt <Overall>
/<Overall>/ {
# evaluate the sum and increment counter
Rate+=;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+=;c++}END{printf("[%s] %f\n",FILENAME,r/(c+(!c))}' ${File}
注:
( c + ( ! c ) )
使用逻辑 NOT (!
) 的副作用。如果 c = 0,它的值为 1,否则为 0。所以如果 c = 0 它加 1,如果不是它加 0 到它自己保证至少 1 的除法值。
- 假设完整文件反映了内容示例
我正在尝试求一个文件中几个数字的平均值,其中包含“<总体>”这一行。
我的代码:
awk -v file=$file '{if (~"<Overall>") {rating+=; count++;}} {rating=rating/count; print file, rating;}}' $file | sed 's/<Overall>//'
我得到
awk: cmd. line:1: (FILENAME=[file] FNR=1) fatal: division by zero attempted
对于每个文件。如果文件确实包含诸如“< Overall >5”
之类的行,我不明白为什么计数会为零编辑: 根据要求,来自(非常大的)输入文件的样本:
<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 是包含
使用如下 Awk
,
awk -F'<Overall>' 'NF==2 {sum+=; 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>
和后面的行会被过滤,数字是</code> 汇总并存储在 <code>sum
变量中,计数在 c
.
END
子句在打印完所有行后执行,这基本上使用 awk
特殊变量 FILENAME
打印文件名,该变量保留已处理文件的名称,平均值为计算 iff 计数不为零。
您无需等到完全阅读文件后才计算平均评分。如果您使用模式而不是 if
语句,这会更简单。您还需要在 尝试增加 rating
.
<Overall>
awk ' ~ /<Overall>/ {rating+=sub("<Overall>", "", ); count++;}
END {rating=rating/(count?count:1); print FILENAME, rating;}' "$file"
(答案已更新以修复调用 sub
时的拼写错误并正确避免除以 0。)
awk -F '>' '
# separator of field if the >
# for line that containt <Overall>
/<Overall>/ {
# evaluate the sum and increment counter
Rate+=;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+=;c++}END{printf("[%s] %f\n",FILENAME,r/(c+(!c))}' ${File}
注:
( c + ( ! c ) )
使用逻辑 NOT (!
) 的副作用。如果 c = 0,它的值为 1,否则为 0。所以如果 c = 0 它加 1,如果不是它加 0 到它自己保证至少 1 的除法值。- 假设完整文件反映了内容示例