从具有重复地址的行中获取平均值

Get average value from lines with duplicate adresses

我写了一个 bash 脚本来运行 tshark 并将结果输出到日志文件。我已将其缩减为仅显示 MAC 地址和天线强度。 (试图用它来计算房间/建筑物中的人数)

其输出如下所示:

c8:85:50:xx:xxxx    -88,-92
d8:fc:93:xx:xxxx    -76,-76
d8:fc:93:xx:xxxx    -76,-76
d8:fc:93:xx:xxxx    -76,-76
7c:c5:37:xx:xxxx    -69,-69
7c:c5:37:xx:xxxx    -67,-67
80:e6:50:xx:xxxx    -86,-86
d8:fc:93:xx:xxxx    -77,-77
d8:fc:93:xx:xxxx    -77,-77
d8:fc:93:xx:xxxx    -79,-79
34:e2:fd:xx:xxxx    -82,-82
34:e2:fd:xx:xxxx    -82,-82
a0:f3:c1:xx:xxxx    -49,-49
a0:f3:c1:xx:xxxx    -61,-61
80:be:05:xx:xxxx    -75,-75
80:be:05:xx:xxxx    -75,-75
80:be:05:xx:xxxx    -77,-77
80:be:05:xx:xxxx    -76,-76
80:be:05:xx:xxxx    -80,-80
a0:f3:c1:xx:xxxx    -49,-49
a0:f3:c1:xx:xxxx    -59,-59
80:e6:50:xx:xxxx    -88,-88
f8:16:54:xx:xxxx    -61,-61
f8:16:54:xx:xxxx    -61,-61
34:e2:fd:xx:xxxx    -81,-81
34:e2:fd:xx:xxxx    -82,-82

如您所见,一些信号被发送了多次。我想获得每个 MAC 地址的平均值。我该怎么做?

所以这个:

a0:f3:c1:xx:xxxx    -49,-49
a0:f3:c1:xx:xxxx    -59,-59

应该变成这样:

a0:f3:c1:xx:xxxx    -54,-54
#!/bin/bash

sort -k 1 file | tr -s " " > output

mac="";
sig1total=0;
sig2total=0;
count=0;
while read -r line; do
    oldmac=$mac;
    mac=$(echo $line | cut -d " " -f1);
    signal1=$(echo $line | cut -d " " -f2 | cut -d "," -f1);
    signal2=$(echo $line | cut -d " " -f2 | cut -d "," -f2);
#   echo "$mac : $signal1 : $signal2";      
    #if true, compute the average of the previous mac addresses
    if [ "$oldmac" != "$mac" ] && [ $count -gt 0 ] ; then
            sigavg1=$(echo "$sig1total / $count" | bc -lq);
            sigavg2=$(echo "$sig2total / $count" | bc -lq);
            echo "$oldmac $sigavg1,$sigavg2";
            sig1total=0;
            sig2total=0;
            count=0;
    fi

    sig1total=$(( $sig1total + $signal1 ));
    sig2total=$(( $sig2total + $signal2 ));
    count=$(( $count + 1 ));

done < output

我期待一个名为 "file" 的文件,其格式与您在上面提供的格式相同,它会删除多余的空格并按 mac 地址排序。然后我读取每一行,如果 mac 地址与我在前一行看到的 mac 地址不同,我输出旧的 mac 地址并计算总和。否则,我只是在当前读取的行上添加信号值,然后增加计数。

结果输出是这样的:

34:e2:fd:xx:xxxx -81.75000000000000000000,-81.75000000000000000000
7c:c5:37:xx:xxxx -68.00000000000000000000,-68.00000000000000000000
80:be:05:xx:xxxx -76.60000000000000000000,-76.60000000000000000000
80:e6:50:xx:xxxx -87.00000000000000000000,-87.00000000000000000000
a0:f3:c1:xx:xxxx -54.50000000000000000000,-54.50000000000000000000
c8:85:50:xx:xxxx -88.00000000000000000000,-92.00000000000000000000
d8:fc:93:xx:xxxx -76.83333333333333333333,-76.83333333333333333333

请注意,您可能需要安装 bc,但其他所有内容都应包含在 GNU 核心实用程序中。

一个选项是使用 awk。使用以下内容创建一个 parse 文件:

BEGIN {} {    
print "Processing mac "  " with values "  
split(, inputArray, ",")
strvalue = mapMac[];

if(strvalue != null){
    split(strvalue, value,",")
    print "    Current value for "  " is " strvalue;
    value[1] += inputArray[1];
    value[2] += inputArray[2];
    value[3]++;
}else{
    value[1] = inputArray[1];
    value[2] = inputArray[2];
    value[3] = 1;
}
strvalue = value[1]","value[2]","value[3];
print "    New value for "  " is " strvalue;
mapMac[] = strvalue;

}
END{ 
    for(item in mapMac){
        split(mapMac[item], value, ",")
        print item " ---> " value[1]/value[3] ", " value[2]/value[3]
    }
}

假设您的输入文件名为 input.txt,像这样调用 awk:

awk -f parse input.txt

您将获得每个 mac 地址的平均值:

a0:f3:c1:xx:xxxx ---> -54.5, -54.5
7c:c5:37:xx:xxxx ---> -68, -68
d8:fc:93:xx:xxxx ---> -76.8333, -76.8333
c8:85:50:xx:xxxx ---> -88, -92
...