Процесс «прочиталзапомнил»



Процесс «прочитал-запомнил»

Крайность, противоположная предыдущему подходу (там мы «пробегали» по данным как можно быстрее), заключается в чтении их в память и последующей обработке после чтения. Рассмотрим несколько версий этой стратегии.

Для начала приведем простой пример: скажем, у нас есть журнал FTP-сервера и требуется узнать, какие файлы скачивались чаще других. Вот несколько строк из журнала FTP-сервера wu-ftpd:

Sun Dec 27 05:18:57 1998 1 nic.funet.fi 11868 /net/ftp.funet.fi/CPAN/

MIRRORING.FROM a _ о a cpan@perl.org ftp 0 *

Sun Dec 27 05:52:28 1998 25 kju.hc.congress.ccc.de 269273 /CPAN/doc/FAQs/FAQ/

PerlFAQ.html a _ о a mozilla@ ftp 0 *

Sun Dec 27 06:15:04 1998 1 rising-sun.media.mit.edu 11868 /CPAN/

MIRRORING. FROM b __ о a root@rising-sun. media, mit. edu ftp 0 *

Sun Dec 27 06:15:05 1998 1 rising-sun.media.mit.edu 35993 /CPAN/RECENT.html b

о а root@rising-sun.media.mit.edu ftp 0

А вот список полей, из которых состоят приведенные выше строки (все подробности о каждом поле ищите в страницах руководств xferlog(B) сервера wu-ftpd).



Номер поля Имя поля
0 current-time (текущее время)
1 transfer-time (время передачи, в секундах)
2 remote-host (удаленный узел)
3 filesize (размер файла)
4 filename (имя файла)
5 transfer-type (тип передачи)
6 special-action-flag (специальный флаг)
7 direction (направление)
8 access-mode (режим доступа)
9 use r name (имя пользователя)
10 service-name (имя службы)
11 authentication-method (меод аутентификации)
12 authenticated-user-id (идентификатор аутентифицированного пользователя)

Вот пример программы, сообщающей о том, какие файлы передавались чаще других:

Sxferlog = "/var/adin/Iog/xferlog";

open(XFERLOG,Sxferlog) or die "Невозможно открыть Sxferlog•$!\n":

while (<XFERLOG>){

$files{(sDlit)[8]}++ }

close(XFERLOG);

for (sort {$files{$b} <=> $files{$a}||$a cmp $b} keys %files){

print "$_:$files{$_}\n"; >

Мы считываем каждую строку файла, используя имя файла в качестве ключа кэша, и увеличиваем значение для этого ключа. Имя файла выделяется из каждой строки журнала при помощи индекса массива, ссылающегося на определенный элемент списка, возвращенного функцией split():

$files{(split)[8]>++;

Вы могли заметить, что элемент, на который мы ссылаемся (8), отличается от 8-го поля из списка полей xferlog, приведенного выше. Это печальные последствия того, что в оригинальном файле отсутствуют разделители полей. Мы разбиваем строки из журнала по пробелам (что является значением по умолчанию для split()), так что дата разбивается на пять отдельных элементов списка.

В этом примере применяется искусный прием - сортировку значений выполняет анонимная функция sort:

for (sort {$files{$b} <=> $files{$a}||$a cmp $b} keys %files){

Обратите внимание, что переменные $а и $b в первой части расположены не в алфавитном порядке. Это приводит к тому, что sort выводит элементы в обратном порядке, т. е. первыми отображаются самые «популярные» файлы. Вторая часть анонимной функции sort ( I $a cmp $о) гарантирует, что файлы с одинаковой популярностью будут перечислены в отсортированном порядке.

Для того чтобы этот сценарий подсчитывал только некоторые файлы и каталоги, можно задать регулярное выражение в качестве первого аргумента для сценария. Например, если добавить

next unless /$ARGV[0]/o;

в цикл while(), можно будет задавать регулярные выражения для ограничения учитываемых файлов. Давайте посмотрим на другой пример подхода «прочитал-запомнил», в котором используется программа «поиска брешей» из предыдущего раздела. В предыдущем примере выводилась информация только об успешной регистрации с сайтов злоумышленника. Узнать о неудавшихся попытках мы не можем. Чтобы получить такую информацию, мы рассмотрим другой файл журнала.



Содержание раздела