Gawk-ing 平均总是 returns 0
Gawk-ing an average always returns 0
我是 Awk 的新手,尽管这是一个常见的问题,但我还是遇到了麻烦 seemingly simple problem。
我正在尝试获取列的平均值,但我的添加似乎不起作用。我的脚本:
BEGIN {FS = ","}
{
AgentDC1 = ;
AgentDC2 = ;
AutoDC1 = ;
AutoDC2 = ;
CallDuration = ;
CallDurationMinutes = ;
CallStart = ;
ConnectTime = ;
num = (CallDuration ? CallDuration : 0)
print num
sum += num;
}
END {print sum;}
当 运行 时,它打印值(在引号中,这正常吗?)但随后将平均值打印为 0(不带引号)。例如:
$ awk -f search.awk callrecords.csv
"644.0"
"149.0"
"397.0"
...
""
"117.0"
"165.0"
""
0
因此空槽被打印为 ""
,并且没有任何内容被添加到总和中。我讨厌 post 如何提问,但我真的被困在这里,none 我发现的其他 SO 很有启发性。
我想引号实际上存在于数据文件中。 awk 不会神奇地删除它们。
在 awk 中,当您像使用数字一样使用变量时,awk 只会忽略变量中的字符,从不能是数字的第一个字符开始。如果变量值没有剩余,awk 使用值 0。
假设您所有的字段实际上都包含引号,num
的值将以引号开头,因此将其用作数字将导致值 0。它仍然打印出 ok,因为它打印为字符串。
这是一个 gawk
解决方案,它也可以处理包含逗号的字段。 FPAT
正则表达式修改自 gawk manual,而函数 fix
改编自同一页面上的一些代码。两者都假定 "normal" CSV 约定,即引用字段中的引号加倍。 (正如@EdMorton 在评论中指出的那样,嵌入的换行符将无法正确处理。)
function fix(x) {
if (substr(x, 1, 1) == "\"")
return gensub(/""/, "\"", "g",
substr(x, 2, length(x) - 2))
else
return x
}
BEGIN {
FPAT = "([^,\"][^,]*|(\"[^\"]*\")+)?
}
{
AgentDC1 = fix()
AgentDC2 = fix()
AutoDC1 = fix()
AutoDC2 = fix()
CallDuration = fix()
CallDurationMinutes = fix()
CallStart = fix()
ConnectTime = fix()
# Unlike the original, this casts num to a number.
# It's unnecessary. sum += CallDuration; would be just fine.
num = CallDuration+0
print num
sum += num
}
END {print sum+0}
您的输入数据中有引号。试试这个:
BEGIN {FS = "\"?,\"?"}
{
gsub(/^"|"$/,"")
AgentDC1 =
AgentDC2 =
AutoDC1 =
AutoDC2 =
CallDuration =
CallDurationMinutes =
CallStart =
ConnectTime =
num = (CallDuration ? CallDuration : 0)
print num
sum += num
}
END {print sum+0}
如果您的字段中有逗号,以上内容将不起作用。
我是 Awk 的新手,尽管这是一个常见的问题,但我还是遇到了麻烦 seemingly simple problem。
我正在尝试获取列的平均值,但我的添加似乎不起作用。我的脚本:
BEGIN {FS = ","}
{
AgentDC1 = ;
AgentDC2 = ;
AutoDC1 = ;
AutoDC2 = ;
CallDuration = ;
CallDurationMinutes = ;
CallStart = ;
ConnectTime = ;
num = (CallDuration ? CallDuration : 0)
print num
sum += num;
}
END {print sum;}
当 运行 时,它打印值(在引号中,这正常吗?)但随后将平均值打印为 0(不带引号)。例如:
$ awk -f search.awk callrecords.csv
"644.0"
"149.0"
"397.0"
...
""
"117.0"
"165.0"
""
0
因此空槽被打印为 ""
,并且没有任何内容被添加到总和中。我讨厌 post 如何提问,但我真的被困在这里,none 我发现的其他 SO 很有启发性。
我想引号实际上存在于数据文件中。 awk 不会神奇地删除它们。
在 awk 中,当您像使用数字一样使用变量时,awk 只会忽略变量中的字符,从不能是数字的第一个字符开始。如果变量值没有剩余,awk 使用值 0。
假设您所有的字段实际上都包含引号,num
的值将以引号开头,因此将其用作数字将导致值 0。它仍然打印出 ok,因为它打印为字符串。
这是一个 gawk
解决方案,它也可以处理包含逗号的字段。 FPAT
正则表达式修改自 gawk manual,而函数 fix
改编自同一页面上的一些代码。两者都假定 "normal" CSV 约定,即引用字段中的引号加倍。 (正如@EdMorton 在评论中指出的那样,嵌入的换行符将无法正确处理。)
function fix(x) {
if (substr(x, 1, 1) == "\"")
return gensub(/""/, "\"", "g",
substr(x, 2, length(x) - 2))
else
return x
}
BEGIN {
FPAT = "([^,\"][^,]*|(\"[^\"]*\")+)?
}
{
AgentDC1 = fix()
AgentDC2 = fix()
AutoDC1 = fix()
AutoDC2 = fix()
CallDuration = fix()
CallDurationMinutes = fix()
CallStart = fix()
ConnectTime = fix()
# Unlike the original, this casts num to a number.
# It's unnecessary. sum += CallDuration; would be just fine.
num = CallDuration+0
print num
sum += num
}
END {print sum+0}
您的输入数据中有引号。试试这个:
BEGIN {FS = "\"?,\"?"}
{
gsub(/^"|"$/,"")
AgentDC1 =
AgentDC2 =
AutoDC1 =
AutoDC2 =
CallDuration =
CallDurationMinutes =
CallStart =
ConnectTime =
num = (CallDuration ? CallDuration : 0)
print num
sum += num
}
END {print sum+0}
如果您的字段中有逗号,以上内容将不起作用。