Re: lug-bg: sum and sort with bash
- Subject: Re: lug-bg: sum and sort with bash
- From: Peter Pentchev <roam@xxxxxxxxxxx>
- Date: Fri, 22 Oct 2004 01:19:08 +0300
On Thu, Oct 21, 2004 at 04:44:40AM -0700, Ivailo Ivanov wrote:
> Zdraveite,
> Imam fail sas sledata struktura:
>
> source-ip-1 dest-ip bytes digit1 digit2 digit3
> source-ip-2 dest-ip bytes digit1 digit2 digit3
> source-ip-1 dest-ip bytes digit1 digit2 digit3
> source-ip-1 dest-ip bytes digit1 digit2 digit3
> -----------------------
> source-ip-n dest-ip bytes digit1 digit2 digit3
>
> Iskam da sortiram source ip-ta ta spriamo sumarnite
> bytes ot vsiako ot tiah. Triabva da se polu4i neshto
> takova, primerno:
>
> 1. source-ip-1 10929Mb
> 2. source-ip-6 1234Mb
> 3. sourceip-24 125Mb
> --------------------
> I taka natatak....
Уф.. бях се засилил да пиша мое предложение, което да се опира на факта,
че командата 'sort' ще подреди редовете по source IP address, така че
след това с един while read src dst t1 t2 t3; do нещо тук; done ще може
да се сумират и изведат лесно, ако наистина се интересуваш *само* от
адреса на източника (т.е. не искаш да броиш входящ трафик, а само
изходящ), но все пак мисля, че най-добрият вариант наистина ще бъде една
база данни, в която да бухаш и входящите, и изходящите, и да правиш след
това SELECT-и оттам.
Все пак, ако наистина се интересуваш само от входящия трафик, това може
да ти свърши работа:
sort traffic.txt | sh sum.sh
...където в sum.sh има следното:
------ begin sum.sh
#!/bin/sh
cursrc=''
curtraf=0
while read src dst t1 t2 t3; do
if [ "$src" != "$cursrc" ]; then
# Polzvame printf, a ne echo -e "$cursrc\t$curtraf", zashtoto
# kakto maj spomenah i v po-ranen mail do lug-bg, vsyshtnost
# njama portable nachin da ubedim echo da izvezhda specialni
# simvoli kato tabulacijata.
[ ! -z "$cursrc" ] && printf '%s\t%d\n' "$cursrc" "$curtraf"
cursrc="$src"
curtraf=0
fi
curtraf=`expr "$curtraf" + "$t1" + "$t2" + "$t3"`
# Ako naistina polzvash bash, a ne sh, i iskash scriptyt ti
# da vyrvi *samo* s bash ili ksh, a ne s sh na razlichni mashini,
# gornijat red mozhe da byde i...
# curtraf=$(($curtraf + $t1 + $t2 + $t3))
done
# Za poslednija adres...
if [ $curtraf -ne 0 ]; then
printf '%s\t%d\n' "$cursrc" "$curtraf"
fi
------ end sum.sh
Ако някой се зачуди защо не съм вкарал самия sort в sum.sh, добре, може
и така, макар че изглежда малко по-странно:
----- begin sum-with-sort.sh
#!/bin/sh
sort "$1" | (
cursrc=''
curtraf=0
while read src dst t1 t2 t3; do
if [ "$src" != "$cursrc" ]; then
# Polzvame printf, a ne echo -e "$cursrc\t$curtraf", zashtoto
# kakto maj spomenah i v po-ranen mail do lug-bg, vsyshtnost
# njama portable nachin da ubedim echo da izvezhda specialni
# simvoli kato tabulacijata.
[ ! -z "$cursrc" ] && printf '%s\t%d\n' "$cursrc" "$curtraf"
cursrc="$src"
curtraf=0
fi
curtraf=`expr "$curtraf" + "$t1" + "$t2" + "$t3"`
# Ako naistina polzvash bash, a ne sh, i iskash scriptyt ti
# da vyrvi *samo* s bash ili ksh, a ne s sh na razlichni mashini,
# gornijat red mozhe da byde i...
# curtraf=$(($curtraf + $t1 + $t2 + $t3))
done
# Za poslednija adres...
echo "RDBG curtraf is $curtraf"
if [ $curtraf -ne 0 ]; then
printf '%s\t%d\n' "$cursrc" "$curtraf"
fi
)
------ end sum-with-sort.sh
Мисля, че ще се съгласите, че вариантът, при който sort е отвън, е
малко по-добър :) Цялата работа е в това, че когато напишете sort |
while, всичко, което е след pipe-а, се изпълнява в отделен шел
(subshell), така че промените, които той прави по променливите, НЕ СА
видими във външния шел, и накрая не можем да изведем резултата за
последните редове (последния адрес), ако този if/printf не е вътре в
subshell-a: горният шел просто няма да получи променените стойности на
$cursrc и $curtraf.
Поздрави,
Петър
--
Peter Pentchev roam@xxxxxxxxxxx roam@xxxxxxxx roam@xxxxxxxxxxx
PGP key: http://people.FreeBSD.org/~roam/roam.key.asc
Key fingerprint FDBA FD79 C26F 3C51 C95E DF9E ED18 B68D 1619 4553
Thit sentence is not self-referential because "thit" is not a word.
Attachment:
pgpRf7ElfDT9q.pgp
Description: PGP signature
|