awk计算给定范围内的位数

时间:2016-07-15 20:09:20

标签: awk

如何计算字段中给定数字范围内的数字的次数?

例如,原始文本foo.txt如下所示:

2,3,4,2,4
2,3,4,32,4
2,3,4,12,4
2,3,4,4,4
2,3,4,,4
2,3,4,15,4
2,3,4,15,4

我想计算字段#4中的数字落在以下范围之间的次数:[0,10)和[10,20],其中下限是包含的,上限不是。

结果应为:

范围0-10:2 范围10-20:3

下面是我的awk代码,但是我的两个范围都得到8600001 awk -f prog.awk foo.txt

#!/usr/range/awk
# prog.awk

BEGIN {
    FS=",";
    $range1=0;
    $range2=0;
}
$4 ~ /[0-9]/ && $4 >= 0 && $4 < 10 { $range1 += 1 };
$4 ~ /[0-9]/ && $4 >= 10 && $4 < 20 { $range2 += 1 };
END {
    print $range1, "\t", $range2;
}

2 个答案:

答案 0 :(得分:3)

$ awk -F, '0<=$4 && $4<10{a++} 10<=$4 && $4<20{b++}  END{printf "range 0-10: %i range 10-20: %i\n",a,b}' foo.txt
range 0-10: 2 range 10-20: 3

如何运作

  • 0<=$4 && $4<10{a++}

    每次第四个字段位于[0,10)时计数。

  • 10<=$4 && $4<20{b++}

    每次第四个字段都在[10,20]时计数。

  • END{printf "range 0-10: %i range 10-20: %i\n",a,b}

    我们读完文件后,会以所需格式打印出结果。

多行版本

对于那些喜欢将代码分散在多行中的人:

awk -F, '
    0<=$4 && $4<10 {
        a++
    } 

    10<=$4 && $4<20{
        b++
    }

    END{
        printf "range 0-10: %i range 10-20: %i\n", a, b
    }
    ' foo.txt

原始代码的修改版本

在awk中,$range1是其编号为range1的字段的值。这不是你想要的。如果您没有引用字段编号,请不要使用$。因此:

BEGIN {
    FS=",";
    range1=0;
    range2=0;
}
$4 ~ /[0-9]/ && $4 >= 0 && $4 < 10 { range1 += 1 };
$4 ~ /[0-9]/ && $4 >= 10 && $4 < 20 { range2 += 1 };
END {
    print range1, "\t", range2;
}

请注意,不必将范围变量初始化为零:零是数值变量的默认值。

答案 1 :(得分:3)

另一个awk

$ awk -F, '$4>=0{a[int($4/10)]++} 
             END{print "range 0-10:" a[0],"range 10-20:" a[1]}' file

range 0-10:2 range 10-20:3

可轻松扩展以涵盖全范围

$ awk -F, '$4>=0{a[int($4/10)]++} 
             END{for(k in a) print "range ["k*10"-"(k+1)*10"):", a[k]}' file

range [0-10): 2
range [10-20): 3
range [30-40): 1