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 00:56:09 +0300
On Thu, Oct 21, 2004 at 04:48:03PM +0300, Georgi Genov wrote:
> Georgi Genov wrote:
>
> >Ivailo Ivanov wrote:
> >
> >> Zdraveite,
> >>Imam fail sas sledata struktura:
> >
> >
> >#!/bin/sh
> >source_ip_db="10.0.1.2 10.0.1.3 10.0.1.4 10.0.1.5 10.0.1.6"
> >for $source_ip in $source_ip_db; do
> >tmp_trafic_ip=`cat trafic.log | grep "$source_ip " | tr -s ' ' | awk
> >'{ print $3 }'`
Само като идея (НЕ критика, НЕ нищо такова, просто идея за оптимизация)
това би могло да бъде доста опростено...
Като начало, cat samo-edin-file | kakvoto-i-da-e в повечето случаи е
ненужно: дори и когато kakvoto-i-da-e не поддържа няколко файла като
параметър (а grep поддържа), то почти сигурно поддържа поне *един* файл
като параметър, а дори и когато и това не става, винаги можеш да си
спестиш един процес, като използваш възможността на всички шелове за
redirection с < и да направиш kakvoto-i-da-e < samo-edin-file.
Това води до първото опростяване:
grep "$source_ip " trafic.log | tr -s ' ' | awk '{print $3}'
Такааа.. какво имаме сега? А, awk всъщност не се впечатлява от повторени
интервали, ако не му е указан изрично разделител, така че спокойно можеш
да си спестиш tr-то: awk няма да се притесни и от:
grep "$source_ip " trafic.log | awk '{print $3}'
А сега следващият момент: awk вероятно може да се справи и със самото
разделяне, и то по повече от един начин. Първото, което ми хрумва,
разбира се, е:
awk "/^$source_ip / {print \$3}"
Има обаче и по-лесен начин, който ще избегне евентуалните проблеми с
интерпретирането на точките в $source_ip като match за какъвто и да е
символ в regular expression, макар и точно в момента това да няма
значение... awk може да сравнява и низове :)
awk '$1 == "'"$source_ip"'" {print $2}'
Тук играта с кавички и апострофи е, за да можем спокойно да сложим
кавичките около source_ip вътре в командния низ на awk. Това, разбира
се, може да бъде направено и още по-просто с escaping:
awk "\$1 == \"$source_ip\" {print \$2}"
Това постига същото, което прави редът с cat | grep | tr | awk горе, с
доста по-малко процеси, доста по-малко заемана от тях памет, доста
по-малко заемано от тях CPU и така нататък. Още веднъж, това го пиша с
най-добри намерения като предложение за оптимизация, не като критика.
Моето предложение ще бъде в отделно съобщение :)
Поздрави,
Петър
--
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
If the meanings of 'true' and 'false' were switched, then this sentence wouldn't be false.
Attachment:
pgp0QEdlErzZM.pgp
Description: PGP signature
|