使用 awk 检测是否存在具有相同且接近数字的系列

问题描述 投票:0回答:1

我有数千个带有整数的文本文件。现在,我想知道哪些文本文件包含包含数十个相同或相近数字的长序列。如果数字之间的差异在

5
左右,我认为数字很接近。一般来说,我想用
0%
100%
之间的百分比值对文本文件进行评级。
0%
意味着所有数字都相等。 100% 意味着这些数字是完全随机的。我想用概率而不是严格的限制来工作。

最小化输入示例:

4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4 4
-> exact 0% as the entire line is one long series of the same number

2 9 21 17 12 2 2 5 4 6 5 6 6 6 7 6 7 5 3 6 6 5 7 7 6 6 5 6 7 6 7 5 7 6 6 6 5 6 6 5 6 78
-> between 0% and 30% as there is a long series with numbers between 5 and 7

20 15 1 2 1 3 2 1 3 18 20 6 12 35 32 35 34 34 34 34 33 34 33 36 44 68 33 32 34 33 53 87
-> between 20% and 40% as there is a series of numbers (32..35), but interrupted by 44+68

12 28 38 44 22 38 16 14 23 45 17 39 29 2 5 15 11 7 2 8 2 14 10 1 14 3 2 2 9 10 4 22 7
-> up to 100% as these numbers are random with out containing series

上述输入线的预期输出范围:

= 0%
> 0% and < 30%
> 10% and < 40%
> 60% and < 100%

目前,我使用百分比标准差:

{
   a += $1;
   b[++i] = $1
} END {
   m = a / NR;
   for (i in b) {
      d += (b[i] - m) ^ 2
   }
   print int(sqrt(d / NR) * 100 / m + 0.5)
}

然后我手动检查所有文本文件,结果低于 100%。这在某种程度上是有效的,但绝不是完美的。有没有更好的方法来检测包含相同或接近数字的长序列的文本文件?

就上下文而言,每个文本文件代表一个用户会话,每个数字代表该分钟内的请求数。例如,

4 7 6
表示用户处于活动状态三分钟,第一分钟发出 4 个请求,第二分钟发出 7 个请求,第三分钟发出 6 个请求。一长串相同或接近的数字通常是机器人而不是人类的标志。

awk
1个回答
0
投票

我不知道你想要如何计算百分比,但下面的内容,使用任何 awk,将告诉你每个输入行中的每个值有多少个“接近”(即加或减你提供的增量)值出现在一个“长”(即您提供的相邻值的一定长度)存在:

$ cat tst.awk
BEGIN {
        delta = (delta == "" ? 2 : delta)
        long  = (long  == "" ? 5 : long)
    }
    {
        numInRange = 0
        rangeBeg = rangeEnd = $1
        for ( i=1; i<=NF; i++ ) {
            valBeg = $i - delta
            valEnd = $i + delta
            posBeg = (i - long >  1 ? i - long : 1)
            posEnd = (i + long < NF ? i + long : NF)
            delete maxRange[i]
            range = 0
            for ( j=posBeg; j<=posEnd; j++ ) {
                if ( (valBeg <= $j) && ($j <= valEnd) ) {
                    range++
                    maxRange[i] = (range > maxRange[i] ? range : maxRange[i])
                }
                else {
                    range = 0
                }
            }
        }
        for ( i=1; i<=NF; i++ ) {
            printf "%d:%d%s", $i, maxRange[i]-1, (i<NF ? OFS : ORS)
        }
    }

$ awk -f tst.awk file
4:5 4:6 4:7 4:8 4:9 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:10 4:9 4:8 4:7 4:6 4:5
2:0 9:0 21:0 17:0 12:0 2:1 2:1 5:5 4:8 6:7 5:8 6:9 6:10 6:9 7:8 6:7 7:6 5:10 3:1 6:5 6:6 5:10 7:8 7:9 6:10 6:10 5:10 6:10 7:10 6:10 7:10 5:10 7:10 6:10 6:10 6:10 5:10 6:9 6:8 5:7 6:6 5:5
20:0 15:0 1:5 2:6 1:6 3:6 2:6 1:6 3:5 18:1 20:1 6:0 12:0 35:3 32:3 35:5 34:8 34:9 34:10 34:9 33:7 34:7 33:5 36:1 44:0 68:0 33:5 32:5 34:5 33:5 34:5 32:5
12:0 28:0 38:0 44:0 22:0 38:0 16:1 14:1 23:0 45:0 17:0 39:0 29:0 2:0 5:0 15:0 11:0 7:0 2:0 8:0 2:0 14:0 10:0 1:2 14:0 3:2 2:2 2:2 9:1 10:1 4:2 22:0 7:0

希望您可以采用这些值并确定您想要计算的任何“百分比”。

© www.soinside.com 2019 - 2024. All rights reserved.