|
ru.perl- RU.PERL ---------------------------------------------------------------------- From : Artem Chuprina 2:5020/400 15 Feb 2002 18:30:15 To : vilfred Subject : Re: дерево каталогов на вложенных хешах... как? -------------------------------------------------------------------------------- Здравствуй, vilfred. AC>> eval чего и на что матерится? Что на входе, я AC>> вроде понял - путь к директории. AC>> А что на выходе должно быть? И чем File::Find не AC>> устраивает? v> ну, как сказать, eval матерится потому что я плохой прогер, но мысль то v> другая, eval просто рекурсивно будет увеличивать число циклов foreach в v> тексте скрипта и соответствующее этим фореачам число циклов, v> вытаскивающих информацию из хеша. v> программа которая делает хеш хешей хешей хешей массивов v> #!/usr/bin/perl v> foreach $lett(qw(meat beer)){ v> foreach $num(qw(war peace)){ v> foreach $tes(qw(one two)){ v> foreach $users(qw(bred pitt)){ v> @{$hhh{$lett}{$num}{$tes}{$users}}=qw(beer vodka); v> } v> } v> } v> } v> print "hash\tsubhash\t subsubhash\tmassives\n"; v> for $let(sort keys %hhh) { v> print "hash $let: (\n"; v> for $nums (sort keys %{$hhh{$let}}) { v> print "\tsubhash $nums (\n\t"; v> for $ltr(sort keys %{$hhh{$let}{$nums}}){ v> print "\tsubsubhash $ltr (\n\t"; v> for $aa(sort keys %{$hhh{$let}{$nums}{$ltr}}){ v> print "\t\t'$aa' => [ "; v> print join " | " => @{$hhh{$let}{$nums}{$ltr}{$aa}}; v> print " ]\n\t"; v> } v> print ")\n\t"; v> } v> print " \t)\n"; v> } v> print ")\n"; v> } v> ** Joe's Own Editor v2.8l ** Copyright (C) 1995 Joseph H. Allen ** v> File hhhsh.pl not changed so no update needed. v> bash-2.05$ ./hhhsh.pl | less v> hash subhash subsubhash massives v> hash beer: ( v> subhash peace ( v> subsubhash one ( v> 'bred' => [ beer | vodka ] v> 'pitt' => [ beer | vodka ] v> ) v> subsubhash two ( v> 'bred' => [ beer | vodka ] v> 'pitt' => [ beer | vodka ] v> ) v> ) v> subhash war ( v> subsubhash one ( v> 'bred' => [ beer | vodka ] v> 'pitt' => [ beer | vodka ] v> ) v> subsubhash two ( v> 'bred' => [ beer | vodka ] v> 'pitt' => [ beer | vodka ] v> ) v> ) v> ) v> hash meat: ( v> subhash peace ( v> subsubhash one ( v> 'bred' => [ beer | vodka ] v> 'pitt' => [ beer | vodka ] v> ) v> subsubhash two ( v> 'bred' => [ beer | vodka ] v> 'pitt' => [ beer | vodka ] v> ) v> ) v> subhash war ( v> subsubhash one ( v> 'bred' => [ beer | vodka ] v> 'pitt' => [ beer | vodka ] v> ) v> subsubhash two ( v> 'bred' => [ beer | vodka ] v> 'pitt' => [ beer | vodka ] v> ) v> ) v> ) v> bash-2.05$ v> Хеши можно строить(я пытался просто раздувать размер скрипта eval'ом, v> но это как-то по идиотски) любой степени вложенности просто прибавляя v> лишний цикл и лишнюю пару фигурных скобок в $hhh{$lett}{$num}{$tes} v> {$users}, т.е. $hhh{$lett}{$num}{$tes}{$users}{$dream} уже будет хешем v> хешей хешей хешей хешей т.д. v> А в конце, используя оператор @{а тут хеш хешей хешей хешей хешей ... v> n+1 ...}=qw(blah blah blah) можно приспособить хешn массивов. Итого это v> будет выглядеть так: v> @{$hhh{$lett}{$num}{$tes}{$users}}=qw(beer vodka); v> но мне не нравится тчо там стоит 4 фореача, т.е. я при помощи eval v> просто напросто увеличиваю число строк содержащих foreach. А без v> foreach нельзя построить дополнительный хеш, т.е. в любом случае это v> раздувание скрипта. Ведь v> $hash{}->{}->{}->{}->{}->{}->{}->{}->{}->{} ... и т.д. нельзя ли v> это как-то по другому сделать, не через eval А допустим глубину v> вложенности, типа подуровней(число этажей вложденных поддиректорий) v> ставить первым элементом массива. Блин, У меня просто хеш хешей, а v> последний элементик это просто массив из файлов в данной директории. И v> первым в этом массиве, нулевым элементом стоит цифра 10, т.е. есть 10 v> этажей(поддиректорий) подхешей. Т.е. проге эта цифра говорит о том, что v> нужно еще 10 раз соорудить конструкцию. Все равно в упор не понимаю, зачем тебе вся эта конструкция. Задачу-то ты какую решаешь? Полностью поставь. v> File::Find у меня выдает листинг директорий сервера в несколько v> мегабайт просто, там 20 гигов лежит всякого. v> пытался сделать так: v> #!/usr/bin/perl v> my $di="/var/www/html/"; v> #my $m="{perl}"; v> &scan($di); v> sub scan { v> my $dir=$_[0]; my $h1=$_[1]; v> my (@files,$filen,$ndir,$n,$mass,@dirs); v> opendir D, $dir or warn "Cannot open $dir: $!" and next; v> @dirs=grep {!(/^\./) && -d "$dir/$_"} readdir D; v> rewinddir D; closedir D; v> for $n(0..$#dirs) { v> $h="$h1\{$dirs[$n]}"; v> $ndir="$dir/$dirs[$n]"; v> #print "\$hash$m$h1\{$dirs[$n]}\n"; v> my $u="\$hhh$m$h1\{$dirs[$n]}"; v> print $u,"\n"; v> eval{"$u"};#тут то оно и должно создавать вложенный подхеш v> #вместо того, чтобы писать каждый раз вручную foreach v> #как это было в первом примере... v> &scan($ndir, $h); v> } v> return 1; v> } v> на выходе скрипт дает v> [root@www genphys]# ./sdir.pl v> $hhh{manual} v> $hhh{manual}{images} v> $hhh{manual}{misc} v> $hhh{manual}{mod} v> $hhh{manual}{mod}{mod_perl} v> $hhh{manual}{search} v> $hhh{manual}{vhosts} v> $hhh{about} v> $hhh{about}{_vti_cnf} v> $hhh{base} v> $hhh{base}{Include} v> $hhh{base}{_vti_cnf} v> $hhh{web} v> ... и т.д. v> дальше условием, просто недоделал, if exists просто пищется информация v> в хеш... но чего-то тут не выходит. Пытался присобачить массив к хешу - v> не выходит. Hу это ладно, разберусь, но не хочется именно eval генерить v> строчки скрипта, чтобы туда всунуть эти самые подхеши и т.д. Красивая v> ведь штука. Потом схожу в ru.unix, спрошу как сделать дамп в памяти что v> скрипт наделал в этом хеше. Далее читать эту всю шнягу за раз и вообще v> можно подумать о другом устройстве файловой системы. Т.е. элемент v> массива содержит тело самого файла, еще всякие перекрестные ссылки, ну, v> принцип хеширования в поиске, как risearch сделан. В обычной файловой v> системе чтобы дописать в начало файла строчку нужно передвинуть весь v> файл вниз просто напросто. А тут, насколько я понял, просто дописать v> нужный элемент. Hо это еще думать нужно, потому что файловая система на v> файловой системе, короче оно все в любом случае будет пользоваться v> старой системой перезаписи. Hу вобщем вот для чего это все v> хеширование... такая вот мысля. И все базы данных тогда просто v> посылаются очень быстро... AC>> Пока это аналог find. Аналогом slocate это AC>> станет, если ты это засунешь в базу AC>> с достаточно быстрым доступом на чтение. Причем AC>> даже не на доступ по индексу, AC>> а на grep. Для чего та структура, которую ты AC>> пытаешься получить, непригодна. v> я пытаюсть совершенно другую структуру получить, вообще другую в v> принципе. Типа сидишь в joe редактируешь файл, все как обычно, v> директории и пр. Hо на самом деле просто напросто правишь кусок v> двоичного файла, и seek'ом перемещаешься по файлу, куда быстрее, типа v> вводишь joe aaa.html, если этих aaa.html много, система предложит v> выбрать нужный из любой директории или как-то еще сделать(потому как v> aaa.html может быть слишком много, ну не знаю, флажок ставить и v> отключать, как нибудь так). За joe не поручусь, а вот с vim это тривиально безо всяких твоих наворотов и бинарных файлов: :new :r !locate aaa.html|grep /aaa\\.html$ :set nomodified <выбираем нужный> gf Естественно, пишется тривиальная функция, которая инкапсулирует первые три команды... То же с файлами на удаленных машинах. Только придется еще введенный URL парсить на предмет протокола и пр. Базируясь на существующем механизме редактирования файлов на удаленных машинах, встроенном в vim. v> Вобщем тут недодумано, но эта идея заводит. v> Потому как очень быстрый доступ к информации, супербыстрый. Могет даже v> с Гуглей и яндехом посморить получится, потому как маскирующий поиск. v> Hу вобщем это сложно все. не XML, но просто сложно объяснить всю v> картинку, что в голове сидит. Значит, картинка еще не сформировалась. v> короче про эту шнягу написал даже чего придумалось, чтобы просто не v> забыть и заново не выдумывать. Если хочешь, кину ссылку. v> но это все ерунда, но как эвал обойти-то, вот в чем вопрос-то, чтобы не v> было его, не потому что у меня не получилось его запустить, а потому, v> что это как-то некрасиво смотрится. Хотя попробую еще раз сделать, v> может со второго раза выйдет. Так ты какую задачу-то решаешь? Создать десятиуровневый хэш без eval можно большим количеством различных способов, в зависимости от того, на основании каких и откуда берущихся данных. Если к первому примеру, то там все данные известны заранее, и примененный тобой способ оптимален. Если следующий уровень становится известен внутри предыдущего, как в случае с File::Find, то в духе sub make_level { my $upper_level = shift; for my $data (каким-то способом полученные данные нашего уровня) { $upper_level->{$data} = {}; make_level($upper_level->{$data}); } } my %hash; make_level(\%hash); Подробности (номер уровня, данные предыдущего или верхнего уровня) по вкусу. -- Artem Chuprina Communiware.net RFC2822: <ran@ran.pp.ru>, FIDO: 2:5020/358.49, ICQ: 13038757 Отправлено через сервер Форумы@mail.ru - http://talk.mail.ru --- ifmail v.2.15dev5 * Origin: Talk.Mail.Ru (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.perl/6359ca7b954f.html, оценка из 5, голосов 10
|