Forum Webscript.Ru
Программирование => Perl => Тема начата: Dart Sidius от 29 Июля 2004, 20:34:35
-
Как енто можно сделать не прибегая ник каким модулям, т.е. ручками. Есть корневой каталог. А из него куча ещё...вот их надо все пройти...
-
Приблезительно вот так :)
&dir(".","\\t");
sub dir($,$){
my $DIR;
my $shift=$_[1];
my $dirr_=$_[0];
opendir($DIR,$dirr_);
print "$shift [$dirr_]\\n";
foreach(readdir($DIR)){
if((-d $_)&&($_ ne \'.\')&&($_ ne \'..\')){&dir($_,"$shift\\t");}
elsif(($_ ne \'.\')&&($_ ne \'..\')){print "$shift $_\\n";}
}
closedir(DIR);
}
-
Dart Sidius
perldoc File::Find
Billi
с софтлинками этот код пробовал?
-
to NeoNox
софтлинками ?? если не затруднит, что это?
-
man ln
проблема в том, что твой скрипт может "убежать" из текущей папки или зациклиться.
-
Пробовать не пробовал, но это вполне возможно (при первой же возможноти попробую)
для верности можно поменять условие
if((-d $_)&&(! -l $_)&&($_ ne \'.\')&&($_ ne \'..\')){&dir($_,"$shift\\t");}
точно должно работать
-
Помогите ламерку... похожего топа не нашёл решил сюда запостить...
Проблема: надо написать скрипт на перле, который:
- в данной директории показывает список папок в ней (только в ней - во влженных не надо) и их размер (соответственно с подпапками считать);
- показывал бы тоже самое, но только размер файлов (во всей папке с подпапками) считал бы не для всех файлов, а только по заданной маски - например выдать размер всех файлов *.doc каждой подпапки в данной папке.
Сам в перле начинающий... надыбал скрипт на форуме, видоизменил (пока только для 1-го случая) - но что-то не пашет:
Код:
#! perl -w
use strict;
sub dir_ls {
my $save_dir;
my $root = shift;
local *DIR_LS;
opendir DIR_LS ,$root;
while (my $file = readdir (DIR_LS) ) {
next if $file =~ /^\\.\\.?$/;
print "$root/$file\\n";
if (-d "$root/$file") {
$count_d++;
dir_ls ("$root/$file");
} else {
$dir_size += (stat("$root/$file"))[7];
$count_f++;
print "$count_f";
}
}
print "\\n\\nTotal -\\nDirs: $count_d\\nFiles: $count_f\\nSize: $dir_size\\n";
}
opendir FDIR, ".";
while($nm = readdir FDIR){
next if ($nm eq ".");
next if ($nm eq "..");
$stat = 0;
$count_f = 0;
$count_d = 0;
$dir_size = 0;
dir_ls ($nm);
}
closedir FDIR;
типа пишет : "Global symbol "$count_d" requires explicit package name" для всех переменных - что не так!? Заранее спасибо, если кто поможет.... ну а если посоветуют ещё и конструкцию для 2-го варианта (чтобы размер файлов по маске считал0 - то будет вообще счастье! Зараенее спасибо!
-
y0sh1, Вам надо малость подправить вот этот вот участочек:
$stat = 0;
$count_f = 0;
$count_d = 0;
$dir_size = 0;
вот на такой хотя бы:my ($stat,$count_f,$count_d,$dir_size)=(0,0,0,0);
-
Ну вот исправил...
Код:
use strict;
my $s_root = \'\';
my $dir_size = 0;
my $t_dir_size = 0;
sub dir_ls {
my $save_dir;
my $root = shift;
local *DIR_LS;
opendir DIR_LS ,$root;
while (my $file = readdir (DIR_LS) ) {
next if $file =~ /^\\.\\.?$/;
print "$root/$file\\n";
if (-d "$root/$file") {
dir_ls ("$root/$file");
} else {
$dir_size += (stat("$root/$file"))[7];
}
}
print "$dir_size\\n";
$t_dir_size += $dir_size;
$dir_size = 0;
}
opendir(D,\'e:/111\');
while($s_root=readdir(D))
{
dir_ls ($s_root);
print "\\nSize of $s_root: $t_dir_size\\n";
}
closedir(D);
только он почему то выводит не директорию e:/111 , а корневую!? Где ошибка!?
-
это Вы вызываете скрипт браузером в "винде"?
тогда Вам надо пользоваться Win32API::File
посудите сами - ну откуда Вашему Apache известно что такое e:/111. :)Dart Sidius:
Есть корневой каталог. А из него куча ещё...вот их надо все пройти...
y0sh1:
только он почему то выводит не директорию e:/111 , а корневую!?
-
AnnA
Сорри, я толькотнедавно засел за перл... апапч мне не нужен... он и не установлен даже.... ставил активперл под винду... пытаюсь скриптом сделать работу с директорией вот и всё ... и не получается.. :(
-
вот здесь
sub dir_ls {
my $save_dir;
my $root = shift;
local *DIR_LS;
вставь
print "Я здесь: $root\\n";
и увидишь где твой скрипт на данный момент.
-
AnnA
посудите сами - ну откуда Вашему Apache известно что такое e:/111
Собственно Perl никогда у Apache не спрашивает, зает ли он такую директорию или нет... :)
При работе Perl скрипта Apache получает только результат работы...
y0sh1
sub dir_ls {
my $save_dir;
my $root = shift;
local *DIR_LS;
opendir DIR_LS ,$root; #!!!!!
$root в твоем скрипте - название папки которая находится в e:/111, но никак не путь к этой папке, естественно, что opendir будет открывать не ту директорию которую надо, а пытаться открыть директорию $root находящуюся в корне (как правило диск на котором установлен Perl)...
Указывай при использовании функции opendir полный путь, и тогда все будет нормально... ;)
-
NeoNox
вставь print "Я здесь: $root\\n"; и увидишь где твой скрипт на данный момент.
вставил... всё равно не понятно, почему проход начинается с корневой директории (из которой запускается скрипт), а не из папки "E:/111"!?
Те почему то не получается передать в рекурсив функцию путь... она идёт из корня... :(
Вот тут посоветовали применить конструкцию вида:
$dir_name="e:\\\\111";
chdir($dir_name);
opendir(D,$dir_name);
!?!? :(
-
Во... нашёл.. точнее мне показали...
while (my $file = readdir (DIR_LS) ) {
next if $file =~ /^\\.\\.?$/;
next if $root =~ /^\\.\\.?$/;
print "file: $root/$file\\n";
if (-d "$root/$file")
{
dir_ls ("$root/$file");
Вот с этой строчкой (выделенной) всё вроде заработало... только почему... что-то я совсем не втыкаю... :(
-
Phoinix
Phoinix:
Указывай при использовании функции opendir полный путь, и тогда все будет нормально...
спасибо что ткнул... только мне надо не то что бы указать, а передать этот путь в функцию... и что-то не очень получалось...
-
y0sh1
только почему... что-то я совсем не втыкаю
Функция readdir возвращает массив в котором первые два элемента являются \'.\' и \'..\'
попробуй набрать в консоли cd .. и и сразу поймешь, почему директория: e:/111/.. является директорией e:/
А эта строка просто, напросто проверяет соответсвие переменной -> .. и при наличии таковой делает следующий цикл...
Вообще проверять Regexp каждый элемент массива - непрактично, проще перед циклом просто напросто два раза повторить readdir:
readdir DIR_LS; readdir DIR_LS;
while (my $file = readdir (DIR_LS) ) {
#next if $file =~ /^\\.\\.?$/;
-
Phoinix:
Вообще проверять Regexp каждый элемент массива - непрактично, проще перед циклом просто напросто два раза повторить readdir:
Это что-то новенькое. Зачем??
-
Вобщем после дня эксперементов наваял я довольно простенький (и наверно всё же кривоватый) скрипт:
use strict;
my $s_root = \'\';
my $dir_size = 0;
my $file_size = 0;
my $t_dir_size = 0;
my $dir_name = \'\';
sub dir_ls {
my $save_dir;
my $root = shift;
local *DIR_LS;
opendir DIR_LS ,$root;
while (my $file = readdir (DIR_LS) ) {
next if $file =~ /^\\.\\.?$/;
next if $root =~ /^\\.\\.?$/;
if (-d "$root/$file") {
dir_ls ("$root/$file");
} else {
$dir_size += (stat("$root/$file"))[7];
}
}
#print "$s_root : $dir_size\\n";
}
$dir_name="e:\\\\111";
chdir($dir_name);
opendir(D,$dir_name);
while($s_root=readdir(D)) {
if (-d "$s_root") {
dir_ls ($s_root);
print "$s_root : $dir_size\\n";
$t_dir_size += $dir_size;
}
else {
$file_size += (stat("$s_root"))[7];
}
$dir_size = 0;
}
closedir(D);
print "Files in root directory: $file_size\\n";
$t_dir_size += $file_size;
print "\\nTotal: $t_dir_size\\n";
Он проходит по заданной папке и выводит объём всех подпапок + отдельно объём файлов в корне указаной папки... Теперь решил прикрутить помимо подсчёта объёма всей подпапки ещё и объём файлов в ней по маске - например *.mp3 - по предложеной на форуме кнструкции:
my $size = 0;
$size += (stat($_))[7] for (glob(\'e:/111/*.mp3\'));
print "Size *.mp3 - $size bite";
Соответственно в скрипт написанный выше добавил:
................
} else {
$dir_size += (stat("$root/$file"))[7];
[b]$dir_size_mp3 += (stat("$root/$file"))[7] for (glob("$root/$file/*.mp3"));[/b]
}
}
#print "$s_root : $dir_size\\n";
}
...............
[b]print "MP3 in: $dir_size_mp3\\n\\n";[/b]
Но что-то не катит... просто записывает в $dir_size_mp3 какое-то число... !?!?!? В чём может быть дело!?
Phoinix
Phoinix:
Вообще проверять Regexp каждый элемент массива - непрактично, проще перед циклом просто напросто два раза повторить readdir:
readdir DIR_LS; readdir DIR_LS; while (my $file = readdir (DIR_LS) ) { #next if $file =~ /^..?$/;
проще действительно... у меня не пошло..... может дело в том, что функция рекурсивно вызывется!?
-
NeoNox
Это что-то новенькое. Зачем??
Вообщем я чаще readdir закидываю в массив, упераю первых два элемента, а потом провожу обработку...
В принципе, палка о двух концах:
Если количество файдов и директорий довольно большое, то выгружать весь список в массив, бессмысленно, тем более при рекурсии, а проверать каждый элемент... ну не знаю... в любом случае эти два элемента всегда первые и всегда два (если не считать корневую директорию)... так не проще ли просто, напросто после открытия директории, два раза получить эти записи, а потом идти дальше???
у меня не пошло..... может дело в том, что функция рекурсивно вызывется!
Что не пошло???
Но что-то не катит... просто записывает в $dir_size_mp3 какое-то число... !?!?!? В чём может быть дело!?
А ты что картинку ожидал увидеть???
[OFF]Может все-таки книжку почитать?[/OFF]
-
Phoinix
Может все-таки книжку почитать?[/quote]
да я знаю, что ламер в перле... читаю конечно... скрипт вроде подправил...