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}

如果您的字段中有逗号,以上内容将不起作用。