Awk:计算每行的模式字段

时间:2016-12-29 20:20:07

标签: bash unix awk

这个让我感到很头疼,仅仅是因为它的厚颜无耻。

我有一个大约15行的文件(名为“votes”)。对于每一行,第一个字段具有候选者的名称,接下来的15个字段具有15个投票,如下所示:

McBoatface y y n y n y y y n n n y n y
McDoodle n n n n n n n n n n n n n n n
Putin y n y n y y n n n n n n n y y
TheLegend27 y y y y y y y y y y y y y y y

y表示是,n表示否

我写了一个awk脚本,计算每个候选人的“y”数,然后用他/她的名字打印出来:

McBoatface 8
McDoodle 0
Putin 6
TheLegend27 15

这是我的试用版:

{
        count=0;

        for(i=$2; i<NF; i++)
        {
             if ($i == "y") count++;
        }
        printf("%s %d \n" $1, count);
}

但是这只会在名字后打印零:

McBoatface 0
McDoodle 0
Putin 0
TheLegend27 0

发生了什么事? i<NF表达式错误吗?

2 个答案:

答案 0 :(得分:3)

另一种方法是在名称(y)之后计算$1 s,如下所示:

$ awk '{ i=$1; $1=""; print i, gsub(/y/,"") }' file
McBoatface 8
McDoodle 0
Putin 6
TheLegend27 15

说明:

{
    i=$1;                  # place name to var i
    $1="";                 # empty name field
    print i, gsub(/y/,"")  # print name and count of all y's
} 

答案 1 :(得分:2)

你想要for(i=2; ...而不是for(i=$2; ...正在发生的是$ 2,可能是“y”或“n”在两种情况下都不会小于NF,所以你永远不会进入你的环。

您还需要i<=NF代替<,以确保您获得最后一票。

$ cat votes.awk
{
    count=0;
    for(i=2; i<=NF; i++) {
      if ($i == "y") count++;
    }
    print $1, count
}

$ awk -f votes.awk votes.txt 
McBoatface 8
McDoodle 0
Putin 6
TheLegend27 15