Ivanovo Linux Users Group -  
Форум Помощь Поиск Вход
Предыдущая Следующая Вверх Тема Программирование / Системное / AWK работает не так как хотелось бы... (6066 хитов)
- Написал(а) hawk Дата 04.02.11 06:13 Отредактировано 04.02.11 06:29
Не знаю, верно ли создаю тему в данной ветке, но не нашел, куда можно было бы пихнуть скрипты. Суть следующая, есть ядерный коллектор, отдающий траф в формате (два дампа):
ip(откуда)     ip(куда)     кол-во пакетов   колво байт

ip(куда)         ip(откуда) кол-во пакетов   колво байт

Этот вывод я сократил, так как порты не интересны, подсчет идет только по внешним ИП адресам чтобы видеть общую нагрузку. Есть скрипт, который дампит в файл данные с коллектора в выше приведенный формат, далее с помощью awk я беру только два столбца
ip(куда) колво байт
и
ip(откуда)  колво байт
не трудно догадаться это входящий и исходящий траф, сам кусок кода выглядит следующим образом:
/bin/cat ${DIR_DUMP}/${SDIR}/${DNAME_EXT} | awk '{print $2,$4}' \
                                          | grep ${NET} | sort -fn \
                                          | awk '{sum[$1]+=$2}END{for(i in sum) print i,sum}' \
                                          | awk '{OFS=" "} $3 = int($2/1048576) {print $1,"==> "$2,"("$3")"}' \
                                          | sort -fn >> ${DIR_SORT}/${SDIR}/${SNAME_EXT};

${DIR_DUMP}/${SDIR}/${DNAME_EXT} - это файл дампа входящего трафа
суммируем по одинаковым адресам второй столбик в котором байты awk '{sum[$1]+=$2}END{for(i in sum) print i,sum}' \
а вот тут сама засада, строка awk '{OFS=" "} $3 = int($2/1048576) {print $1,"==> "$2,"("$3")"}' \ выводит в файл данные в виде
IP1   байт  (мб)
т.е. в скобках добавляет еще Мегабайты для лучшего восприятия, и что выходит, если сумма хранящаяся в $2 мала то при делении на 1048576 получаем ноль целых ноль ноль ноль ноль, и вобщем строка из отчета с этим IP просто выпадает - ее нет, если блок кода привести к следующей форме
/bin/cat ${DIR_DUMP}/${SDIR}/${DNAME_EXT} | awk '{print $2,$4}' \
                                          | grep ${NET} | sort -fn \
                                          | awk '{sum[$1]+=$2}END{for(i in sum) print i,sum}' \
                                          | sort -fn >> ${DIR_SORT}/${SDIR}/${SNAME_EXT};
без преобразований в Мб, все IP на месте, но читать не удобняк, вот и вопрос, как сделать чтобы не терялась строка, когда делим и получаем ноль целых.

P/s LOE движок по тексту [ i ] воспринимает как начало курсива и автозаканчивает эти теги самостоятельно, оформляя текст курсивом.
echo "good..." | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see'
Parent - Написал(а) LOE (Site/forum admin) Дата 04.02.11 07:10 Отредактировано 04.02.11 07:17
Странно, почему awk пропускает при выводе строку, если ее результат ноль.

Но лично я, не очень люблю делать такие пайпы. Максимум если надо 1 или 2 раза вызвать тот-же awk. Если больше - уже проще написать скриптик на том-же perl'е:
$ cat dan
0.1.2.3 123456789
1.2.3.4 1023
2.3.4.5 1
6.7.8.9 5
$ cat p.pl

while(<STDIN>) {
        chop;
        (@D)=split(/[ \t]+/,$_);
        $S{$D[0]}+=$D[1];
}
map {
        printf("%s %s (%.3f)\n",$_,$S{$_},$S{$_}/1048576);
} keys %S;

$ cat dan | perl p.pl
2.3.4.5 1 (0.000)
1.2.3.4 1023 (0.001)
6.7.8.9 5 (0.000)
0.1.2.3 123456789 (117.738)

Зато, появляется возможность в одном месте сделать всё, что требуется, оформить как хочется и сделать еще кучу вещей :-)

PS. да, написанные слитно [i] приводят к отработке форматирования. Либо вставить пробелы, либо (как я сейчас), "замаскировать" другими конструкциями ;-)
"No! Try not! Do. Or do not. There is no try." -- Yoda
Parent Написал(а) hawk Дата 04.02.11 07:35 Отредактировано 04.02.11 08:21
С perl надо подразобраться :-), спасибо за пример.
Похоже решил проблему, видоизменив строку вот так:
awk '{OFMT="%.4f"; $3 = int($2/1048576)} {print $1,"==> "$2,"("$3")"}' \
т.е. еще учел формат цифирь, что они не целочисленные. Теперь, очень мелкие значения просто
45343 (0) - т.е. первое байты, потом 0 мегабайт, как задумывалось в общем.
echo "good..." | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see'
Предыдущая Следующая Вверх Тема Программирование / Системное / AWK работает не так как хотелось бы... (6066 хитов)

Powered by mwForum 2.12.0 © 1999-2007 Markus Wichitill

Page created in 0.086s with 11 database queries.