![]() |
![]() |
||||||
| . | ........ | . | ........ | . | Январь / 2000 | ||
| . | Стандарт CGI (Common Gateway Interface) изначально был разработан для того, чтобы дать возможность пользователям запускать программы, доступные на сервере, через Web. Первые CGI программы служили простым интерфейсом для стандартных команд grep и finger, преобразовывали информацию, выдаваемую этими командами, в формат HTML и передавали полученные результаты броузеру пользователя. | . |
Простая поисковая система. Поиск на вашем Web - сайте - это просто. Введение в методику поиска. Рэйвен М. Лернер Linux Journal, #69, Январь 2000 Перевод с английского: Игорь Грень gren@open.by perl -ne 'print if m/foo/' test.txt Ключ -n приказывает не выводить все строки по умолчанию, а -e дает нам возможность вставить вызов команды между одиночными кавычками ('). Мы просим Perl выводить каждую строку, в которой оператор m// (совпадение) найдет указанное слово. Выполнение этой задачи мы можем вставить в программу, как показано на Листинге 1. Listing 1. simple-search-1.pl #!/usr/bin/perl -w use strict; use diagnostics; # Open the file my $filename = "test.txt"; open FILE, $filename or die qq{Cannot read "$filename": $! }; # Iterate through each line of the file, # printing all lines that match while (<FILE>) { print if m/foo/; } close FILE; Конечно, эта программа выполняет поиск по простой конкретной маске (строка "foo") внутри одного конкретного файла (test.txt). Мы можем расширить поле действия программы, используя пустой указатель <> вместо поиска в <FILE>. Пустой указатель <> просматривает каждый элемент в @ARGV (массив аргументов командной строки), присваивая значение каждого элемента массива переменной $ARGV. Если командная строка не содержит аргументов, <> ожидает ввода данных от пользователя. Листинг 2 содержит модифицированную версию программы, которая выполняет поиск строки "foo" в нескольких файлах. Обратите внимание на то, что эта программа уже выводит вместе с найденной строкой и название файла. Так как $_ уже содержит символ перевода на новую строку, нам не нужно добавлять его в конце каждой команды print. Второй листинг можно тоже свести к одной командной строке вызова Perl: perl -ne 'print "$ARGV: $_" if m/foo/;' * Listing 2. simple--search--2.pl #!/usr/bin/perl -w use strict; use diagnostics; # Iterate through each line of each file while (<>) { # Print the matching filename and line print "$ARGV: $_" if m/foo/; } Теперь мы можем усложнить нашу программу и разрешить пользователю указать маску для поиска и названия файлов - объектов поиска. Программа в Листинге 3 берет первый аргумент командной строки, удаляет его из @ARGV и переносит в $pattern. Чтобы Perl понял, что $pattern не изменится и поиск выполняется только один раз, мы используем m// с параметром /o. Listing 3. simple-search-3.pl #!/usr/bin/perl -w use strict; use diagnostics; # Get the pattern my $pattern = shift @ARGV; # Iterate through each line of each file while (<>) { # Print the matching filename and line print "$ARGV: $_" if m/$pattern/o;<\n> } Теперь для поиска строки f.[aeiou] во всех файлах с расширением "txt" мы используем: ./simple-search-3.pl "f.[aeiou]" *.txt Можете быть уверены, что теперь каждая строка, которая содержит символ f, после которого следует гласная буква, указанная в квадратных скобках, отобразится на экране вместе с именем файла. File::Find Программа, приведенная выше, может служить хорошей основой для Web-поиска, если все документы на Web-сайте хранятся в одном каталоге. Но в реальной жизни большинство Web-сайтов представляет собой весьма разветвленную иерархическую систему подкаталогов, заполненных файлами. Хорошая поисковая программа должна пройтись по всей иерархии Web-сайта, просмотреть каждый файл в каждом подкаталоге. Пока мы старались выполнить эту задачу самостоятельно, кто-то уже поработал за нас. Модуль File::Find, который входит в состав Perl, позволяет создавать программы, аналогичные find, на этом языке. File::Find экспортирует подпрограмму find, которой можно передавать список аргументов. Первый аргумент- это ссылка на подпрограмму, которая вызывается для каждого найденного файла. Остальные аргументы - это названия каталогов и файлов, которые File::Find будет просматривать последовательно, пока не доберется до последнего. Например, в Листинге 4 приведена программа, использующая File::Find для вывода списка файлов, хранимых в конкретном каталоге. Как видно, File::Find экспортирует переменную $File::Find::name, которая содержит текущее имя файла. Название текущего каталога помещается в $File::Find::dir. Listing 4. simple-find.pl #!/usr/bin/perl -w use strict; use diagnostics; use File::Find; # Invoke "find" with a reference to our # subroutine, and the initial directory name find(\&print_name, "/home/reuven"); sub print_name { print "$File::Find::name\n"; } Listing 5: simple-find-2.pl #!/usr/bin/perl -w use strict; use diagnostics; use File::Find; # Get the pattern from the input list my $pattern = shift @ARGV; # Slurp up the entire contents of a file $/ = undef; print qq{Searching for "$pattern".\n}; # Invoke "find" with a reference to our subroutine, # with the directories passed as arguments find(\&find_matches, @ARGV); sub find_matches { my $filename = $_; # Open the file, and search through its # contents if (open FILE, $filename) { # Get the file my $contents = (<FILE>); # If there aren't any contents, then return # right away return unless $contents; # Print the filename, with the directory print qq{$File::Find::dir/$filename\n} if ($contents =~ m|\b$pattern\b|is); close FILE; } else { warn qq{Unable to open "$File::Find::dir/$filename": $! }; return; } } В Листинге 5 приведена программа simple-find-2.pl, которая использует File::Find для поиска в файлах, находящихся в каталогах, помещенных в указанный заданный каталог. Как и в других программах, использующих File::Find, основная работа simple-find-2.pl выполняется find_matches, подпрограммой, вызываемой для обработки каждого файла, найденного в каталогах, перечень которых содержит массив @ARGV. Чтобы найти все файлы, содержащие слово "f.[aeiou]" в каталогах /home and /development, печатаем: ./simple-find-2.pl "f.[aeiou]" /home /development Строка 8 программы simple-find-2.pl имеет особое значение: она переназначает $/, переменную, которая определяет символ конца строки. Обычно оператор <> просматривает файл строка за строкой, возвращая undef при достижении конца строки. Но мы хотим производить поиск во всем файле, даже если искомое слово или фраза будут начинаться на одной строке, а заканчиваться на другой. После переопределения $/, строка my $contents = (<FILE>); переносит все содержимое файла FILE в переменную $contents, а не только одну строку. Продолжение |
Содержание ........ Трехмерные миры в Web: VRML Виталий Фридман ........ Простая поисковая система Рэйвен М. Лернер Linux Journal, #69, Январь 2000 ........ Интернет коммерция в Беларуси Дмитрий Шейко ........ Гиперссылка на любимую телепередачу Алиса Бизяева ........ Quake. Третье пришествие Денис Москаленко ........ |