Команда Awk для объединения строк и их суммирования - PullRequest
0 голосов
/ 06 апреля 2011

Это формат, который у меня есть.

Source IP       Destination IP    Received Sent
192.168.0.1     10.10.10.1        3412     341
192.168.0.1     10.10.10.1        341      43
192.168.0.1     10.22.22.2        34       334
192.168.0.1     192.168.9.3       34       243

Но очень большой файл этих. Я в основном хочу дать общую пропускную способность каждого источника IP. Поэтому мне нужно объединить все исходные IP-адреса Uniq, а затем добавить полученные столбцы всего уникального, а затем добавить отправленные столбцы. Конечный результат будет:

source ip - общее количество принятых пакетов - общее количество отправленных пакетов

Было бы также неплохо указать IP-адрес источника и получателя, чтобы я мог также получить

source ip - ip получателя - общее количество принятых пакетов - общее количество отправленных пакетов

Любая помощь будет принята с благодарностью

Ответы [ 4 ]

2 голосов
/ 06 апреля 2011

только глядя на IP-адрес источника:

awk '
    NR == 1 {next}
    {
        recv[$1] += $3
        sent[$1] += $4
    }
    END {for (ip in recv) printf("%s - %d - %d\n", ip, recv[ip], sent[ip]}
' filename

для пар источник / приемник, просто небольшое изменение:

awk '
    NR == 1 {next}
    {
        key = $1 " - " $2
        recv[key] += $3
        sent[key] += $4
    }
    END {for (key in recv) printf("%s - %d - %d\n", key, recv[key], sent[key])}
' filename
1 голос
/ 06 апреля 2011

Рубин (1,9 +)

#!/usr/bin/env ruby      
hash_recv=Hash.new(0)
hash_sent=Hash.new(0)
hash_src_dst_recv=Hash.new(0)
hash_src_dst_sent=Hash.new(0)
f=File.open("file")
f.readline
f.each do |line|
    s = line.split
    hash_recv[s[0]] += s[2].to_i
    hash_sent[s[0]] +=  s[-1].to_i
    hash_src_dst_recv[ s[0,2] ] +=  s[2].to_i
    hash_src_dst_sent[ s[0,2] ] +=  s[-1].to_i
end
f.close
p hash_recv
p hash_sent
p hash_src_dst_recv
p hash_src_dst_sent

тестовый прогон:

$ ruby test.rb
{"192.168.0.1"=>3787, "192.168.168.0.1"=>34}
{"192.168.0.1"=>718, "192.168.168.0.1"=>243}
{["192.168.0.1", "10.10.10.1"]=>3753, ["192.168.0.1", "10.22.22.2"]=>34, ["192.168.168.0.1", "192.168.9.3"]=>34}
{["192.168.0.1", "10.10.10.1"]=>384, ["192.168.0.1", "10.22.22.2"]=>334, ["192.168.168.0.1", "192.168.9.3"]=>243}
0 голосов
/ 06 апреля 2011
 awk '{
       if (NR==FNR){ 
         Recieved[$1,$2]+=$3;Sent[$1,$2]+=$4;
       }else{
           if(Recieved[$1,$2]){
             print $1" " $2" " Recieved[$1,$2]" "Sent[$1,$2];Recieved[$1,$2]=""
           }
       }
      }' InputFile.txt InputFile.txt

InputFile читается дважды, следовательно, он добавляется два раза в конце.Первый случай ввода файла ввода (, который используется в условии if (NR == FNR) ) для построения двух массивов, а второй файл ввода (, используемый в условии else ), - для печатикомбинации, а также установка значения массива пустым, чтобы мы не печатали снова.

Приведенное ниже решение Гленна намного лучше, оно читает файл только один раз

0 голосов
/ 06 апреля 2011

Я бы сделал (немного отформатированный, но вы могли бы написать это в одну строку):

sort file.txt | awk ' BEGIN {start = 1;} 
                           { 
                            ip = $1; 
                            if (lastip == ip) { 
                               sum_r += $3; sum_s += $4; 
                               }
                            else 
                               { if (!start) print lastip ": " sum_r ", " sum_s
                                 else 
                                    start = 0;
                                 lastip = ip; sum_r = $3; sum_s = $4;
                                }
                            }
                       END { print lastip ": " sum_r ", " sum_s }'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...