Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Perl: Общие вопросы > Рекурсивный обход каталога и вывод в виде tree |
Автор: dimdiden 23.1.2015, 10:48 |
Привет всем! Светлые умы, помогите пожалуйста с алгоритмом действия по такому заданию: Необходимо написать программу которая выведет от заданной директории все файлы и поддиректории в псевдографическом виде. Как в утилите tree: . ├── config.dat ├── data │ ├── data1.bin │ ├── data2.sql │ └── data3.inf ├── images │ ├── background.jpg │ ├── icon.gif │ └── logo.jpg ├── program.exe └── readme.txt Условия: не пользоваться модулями. Описание: Вот с этого сайта понял как делать рекурсивный обход директории http://perlmaven.com/recursive-subroutines use strict; use warnings; use 5.010; my $path = shift || '.'; traverse($path); sub traverse { my ($thing) = @_; say $thing; return if not -d $thing; opendir my $dh, $thing or die; while (my $sub = readdir $dh) { next if $sub eq '.' or $sub eq '..'; traverse("$thing/$sub"); } close $dh; return; } Т.е. просто перечень всех файлов и поддиректорий я вывожу. Но натолкните пожалуйста на мысль, как организовать вот эти вот "сдвиги вправо" древовидно по каждой субдиректории как в команде tree? У меня была мысль каким то образом сделать "хэш хэшей" где ключ - поддиректория а значение - уровень вложенности. Но думаю это довольно сложно, есть путь и попроще. Заранее спасибо! |
Автор: alezzz 23.1.2015, 14:45 |
передавай уровень в функцию, например traverse("$thing/$sub", ++$level); это универсально, а в данном случае кажется можно и слеши посчитать в пути. Добавлено через 13 минут и 46 секунд с ++$level в функции это я погорячился, проверил на вашем примере, сильно сдвигает, лучше сделать $level++ перед while |
Автор: dimdiden 23.1.2015, 15:05 |
Вот это мы должны передавать когда наш $thing/$sub является директорией. Но счетчик $level будет плюсоваться при каждой встрече директории, даже если это второй уровень вложенности - если субдиректорий было много, счетчик уже не будет со значением 2. Я понимаю, Вы сказали в общем, принцип действия. Но я нубоват, если можно чуток бы по подробнее. Спасибо. |
Автор: alezzz 23.1.2015, 17:24 |
Я ж потом добавил что инкремент при передаче в функцию неправильно делать. Делайте $level++ например после say и передавайте traverse("$thing/$sub", $level) |
Автор: dimdiden 23.1.2015, 17:33 |
Не увидел, сори. |
Автор: dimdiden 24.1.2015, 00:24 | ||
Покрутил немного с советом что был дан выше Теперь код имеет вид:
Выхлоп в таком виде: + +----efi +--------EFI +------------redhat +----------------grub.efi +----vmlinuz-2.6.32-431.el6.x86_64 +----initramfs-2.6.32-431.el6.x86_64.img +----.vmlinuz-2.6.32-431.el6.x86_64.hmac +----grub +--------device.map +--------menu.lst +--------jfs_stage1_5 +--------reiserfs_stage1_5 +----config-2.6.32-431.el6.x86_64 +----System.map-2.6.32-431.el6.x86_64 Необходимо дальше решать задачу: 1. Из за цикла while читается поочередно каждый элемент. Естественно, из за этого файлы которые находятся в корне директории могут идти вразнобой с субдиректориями, что видно выше. Наверное надо все элементы загонять в массив или хэш и там уже как то сортировать? 2. Куда копать, что бы графическое предствление (+---) содержимого субдиректории начиналось с сасмой субдиректории? Спасибо! |
Автор: alezzz 26.1.2015, 08:06 |
По п.1 можно и загуглить: http://stackoverflow.com/questions/16793043/perl-readdir-in-order |
Автор: dimdiden 27.2.2015, 20:19 | ||||||
Привет всем опять! Пока что дошел вот до такого уровня:
Вывод такого плана:
А надо, естественно, что бы вот так было:
Подскажите пожалуйста в какую сторону двигаться! |