_ RU.UNIX.BSD (2:5077/15.22) _____________________________________ RU.UNIX.BSD _
From : Igor Sysoev 2:5020/400 03 Aug 99 10:52:10
Subj : Re: rexx
________________________________________________________________________________
From: "Igor Sysoev" <[email protected]>
Andy Bogdanov wrote in message <[email protected]>...
> IS> О как - однозначно. Интересно, чем же однозначно ? Для предметности
> IS> обсуждения, возмем лог апачи и вытащим из него хосты и урлы
> IS> к которым эти хосты обращалсиь, при условии, что броузер у там
> IS> "Mozilla/4.0 (compatible; MSIE 4.01; Windows NT)"
> IS> Одна строка из лога выглядит примерно так:
>
> IS> igor.nitek.ru - - [02/Aug/1999:12:55:39 +0400]
> IS> "GET /~igor/ HTTP/1.1" 200 5238 "-"
> IS> "Mozilla/4.0 (compatible; MSIE 4.01; Windows NT)"
> IS> "www.nitek.ru" "-"
>
> IS> Скрипт, который делает описанную выше задачу:
>
> IS> $LOG = '^(\S+) \S+ \S+ \[([^\]]+)\] "([^"]+)" ' .
> IS> '(\S+) (\S+) "([^"]+)" "([^"]+)" "([^"]+)" "([^"]+)"\r?$' ;
>
> IS> while (<>) {
> IS> if (($host, $date, $url, $res, $size,
> IS> $ref, $agent, $www, $forward) = /$LOG/o) {
> IS> print "$host, $url\n" if
> IS> $agent =~ m{^Mozilla/4.0 \(compatible; MSIE 4.01; Windows NT\)$}
> IS> ;
> IS> }
> IS> }
>
> IS> Как это будет выглядет на рексе ?
>померяемся пиписьками? :)
>
>#!/usr/local/bin/rexx -x
>
>trace off
>log=/var/log/www/access_log
>
>do while Lines(log) \= 0
> lin=LineIn(log)
> host=Word(lin,1)
> url=Word(lin,WordPos('"GET',lin)+1)
> agent='"Mozilla/4.0 (compatible; MSIE 4.01; Windows NT)"'
> if (WordPos(agent,lin) > 0)||(url \='/') then say host url' - 'agent
>end
>
>exit
>:)
>
>результатом будет
>
>igor.nitek.ru/~igor/ - "Mozilla/4.0 (compatible; MSIE 4.01; Windows NT)"
>
>
>по моему, прочитать намного проще :)
Hет, право слово, из приведенного кода я не вижу никаких преимуществ,
тем более однозначных.
1. Искать url по "GET просто не серьезно. Да и остальные поиски по
WordPos тоже не серьезны. Где гарантия, что подобные строки
не встрется три раза ? И из этих трех раз нам нужен только второй.
2. Почему в "if (WordPos(agent,lin) > 0)||(url \='/') then"
стоит ||, а не && ? Если это не опечатка, то это напоминает
шелл с перевернутым понимаением true и false. Лично мне такое читать
сложно.
3. Мой скрипт очень легко изменяем для генерации произвольных выборок,
например, если мне нужно выдать список хостов, запрошенных урлов
и урлов, с которых на эти запрошенные урлы пришли, то это делается так:
$LOG = '^(\S+) \S+ \S+ \[([^\]]+)\] "([^"]+)" ' .
'(\S+) (\S+) "([^"]+)" "([^"]+)" "([^"]+)" "([^"]+)"\r?$' ;
while (<>) {
if (($host, $date, $url, $res, $size,
$ref, $agent, $www, $forward) = /$LOG/o) {
print "$host : $url : $ref\n"
}
}
Результатом будет:
igor.nitek.ru : GET /~igor/ HTTP/1.1 : -
Вместо последней черточки может быть, в частности, следующее:
http://www.yandex.ru/yandbtm2?b=2&q=2026649984&p=0&d=0&text=pppd
news://193.232.230.33/7n3qab%246s1%241%40gate.nitek.ru
file://localhost/tmp/L6217-1TMP.html
wysiwyg://141/http://www.nitek.ru:8101/~igor/pppd/connect.html
и, наконец, просто какая-нибудь туфта.
Regex - великое изобретение. Hужно один раз сесть, напрячься и
понять их. Тем более, что они логичны и достаточно просты.
Тогда строки вида '^(\S+) \S+ \S+ \[([^\]]+)\] "([^"]+)"' не будут
пугать, а многие проблемы будут легко решатся такой парой строк.
С уважением,
Игорь Сысоев
http://www.nitek.ru/~igor/--- ifmail v.2.14dev3 * Origin: NITEK Corporation (2:5020/400)