#linux #scripting #awk
#linux #создание сценариев #awk
Вопрос:
Это формат, который у меня есть.
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, а затем добавить полученные столбцы всего, что уникально, а затем добавить отправленные столбцы. Конечным результатом было бы:
ip-адрес источника — общее количество полученных пакетов — общее количество отправленных пакетов
Также было бы неплохо унифицировать IP-адреса источника и назначения, чтобы я мог также получить
ip источника — ip назначения — общее количество полученных пакетов — общее количество отправленных пакетов
Буду признателен за любую помощь
Ответ №1:
просто смотрю на исходный IP:
awk '
NR == 1 {next}
{
recv[$1] = $3
sent[$1] = $4
}
END {for (ip in recv) printf("%s - %d - %dn", 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 - %dn", key, recv[key], sent[key])}
' filename
Ответ №2:
Ruby (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}
Комментарии:
1. @MJB, OP также поместил тег в «scripting». Это не обязательно должно быть
awk
.
Ответ №3:
Я бы сделал (немного отформатированный, но вы могли бы записать его в одной строке):
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 }'
Ответ №4:
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)) заключается в построении двух массивов, а второй inputfile (используемый в условии else) предназначен для печати всех комбинаций, а также для установки значения массива пустым, чтобы мы не печатали снова.
Решение Гленна, приведенное ниже, намного лучше, оно считывает файл только один раз