2015-07-20 5 views
1

Я написал сценарий 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 

ответ

1

Опция заключается в использовании awk. Создание разбора файл со следующим содержимым:

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

if(strvalue != null){ 
    split(strvalue, value,",") 
    print " Current value for " $1 " 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 " $1 " is " strvalue; 
mapMac[$1] = 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 

вы получите среднедушевой макинтош адрес:

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 
... 
+0

Спасибо, это сработало. Просто пришлось обрезать вывод, чтобы использовать только 1 десятичное число с% .1f (для моих целей). – Mars

0
#!/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 

Я ожидаю, что файл с именем "файл" с форматом вы указали выше, обрезает лишние пробелы & сортирует его по 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.

+0

Спасибо, это сработало! – Mars