我是Awk的新手,虽然这是一个常见的seemingly simple problem,但我遇到了麻烦。
我想要获得列的平均值,但我的添加似乎无法正常工作。我的剧本:
BEGIN {FS = ","}
{
AgentDC1 = $4;
AgentDC2 = $5;
AutoDC1 = $23;
AutoDC2 = $24;
CallDuration = $28;
CallDurationMinutes = $27;
CallStart = $33;
ConnectTime = $35;
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
所以空插槽正在打印为""
,并且没有任何内容添加到总和中。我讨厌发布如何解决问题,但我真的被困在这里,我找到的其他SO都不是很有启发性。
答案 0 :(得分:2)
我认为引号实际上存在于数据文件中。 Awk不会神奇地删除它们。
在awk中,当你使用变量就好像它是一个数字时,awk只是忽略变量中的字符,从第一个不能成为数字的部分开始。如果变量的值没有剩余,则awk使用值0。
假设您的所有字段实际上都包含引号,num
的值将以引号开头,因此将其用作数字将导致值为0.它仍然打印出来,因为它已打印作为一个字符串。
这是一个gawk
解决方案,它也可以处理包含逗号的字段。 FPAT
正则表达式已从gawk manual修改,而函数fix
则根据同一页面上的某些代码进行了修改。两者都假设"正常"引用字段中引号的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($4)
AgentDC2 = fix($5)
AutoDC1 = fix($23)
AutoDC2 = fix($24)
CallDuration = fix($28)
CallDurationMinutes = fix($27)
CallStart = fix($33)
ConnectTime = fix($35)
# 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}
答案 1 :(得分:2)
您的输入数据中有引号。试试这个:
BEGIN {FS = "\"?,\"?"}
{
gsub(/^"|"$/,"")
AgentDC1 = $4
AgentDC2 = $5
AutoDC1 = $23
AutoDC2 = $24
CallDuration = $28
CallDurationMinutes = $27
CallStart = $33
ConnectTime = $35
num = (CallDuration ? CallDuration : 0)
print num
sum += num
}
END {print sum+0}
如果您的字段中包含逗号,则上述操作无效。