Модераторы: korob2001, ginnie
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Тема в фак, Хочу написать о рекурсии. 
:(
    Опции темы
Secandr
Дата 20.7.2004, 09:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



подскажите, что сделать, что бы работала рекурсия в перле?
Код
#!/usr/bin/perl
print "!!";
open PL,'>pl.txt' or die "file pl.txt not open";

read_dir("/home");

sub read_dir(){
   my $n,$t;
   my $name= shift;
   opendir dr, $name;
   while ($n=readdir(dr))
{
if (-f "$name/$n")
    {
    $t="$name/$n\n";
    print PL "$t";
    }
elsif ( ($n ne '.')and($n ne '..'))
    {
    read_dir("$name/$n");
    }
}
   closedir dr;
}
close PL;

Добавлено @ 09:14
Вот код без рекурсии, работает вполне великолепно:
Код
#!/usr/bin/perl
print "!!";
@dir=("/home");
open PL,'>pl.txt' or die "file pl.txt not open";

while ($name= shift @dir)
   {
   opendir dr, $name;
   while ($n=readdir(dr))
{
if (-f "$name/$n")
    {
    $t="$name/$n\n";
    print PL "$t";
    }
    }
elsif ( ($n ne '.')and($n ne '..'))
    {
    push @dir,"$name/$n";
    }
}
   closedir dr;
   }
close PL;

Добавлено @ 09:15
сразу убъю двух зайцев - напишу про рекурсию и про работу с деррикториями.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
dimes
Дата 20.7.2004, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 249
Регистрация: 20.7.2004
Где: то около СПБ

Репутация: нет
Всего: 14



my $h;
opendir ($h,"dir");
........
либо
local *h;
opendir (h,"dir");
.......
PM ICQ   Вверх
Secandr
Дата 20.7.2004, 09:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



dimes
спасибо.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
y0sh1
Дата 26.8.2004, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.8.2004

Репутация: нет
Всего: нет



Проблема: надо написать скрипт на перле, который:
- в данной директории показывает список папок в ней (только в ней - во влженных не надо) и их размер (соответственно с подпапками считать);
- показывал бы тоже самое, но только размер файлов (во всей папке с подпапками) считал бы не для всех файлов, а только по заданной маски - например выдать размер всех файлов *.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 - то будет вообще счастье! Зараенее спасибо!
PM MAIL   Вверх
korob2001
Дата 26.8.2004, 11:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2871
Регистрация: 29.12.2002

Репутация: 31
Всего: 61



В одном топике, один вопрос. Это правила форума. Попробуй этот код.
Код

#!/usr/bin/perl

use strict;
my( $count_d, $dir_size, $count_f, $stat, $ed );
$ed = 'byte';
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";
             }
      }

  if ( $dir_size > 1024 ) {
       $dir_size = sprintf("%.1f", $dir_size / 1024 );
       $ed = 'KB';
  }

  if ( $dir_size > 1024 ) {
       $dir_size = sprintf("%.1f", $dir_size / 1024 );
       $ed = 'MB';
  }
 print "\n\nTotal -\nDirs: $count_d\nFiles: $count_f\nSize: ${dir_size} $ed\n";
 print "-" x 80, "\n";
}

opendir FDIR, ".";
while( my $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;

Удачи.

Это сообщение отредактировал(а) korob2001 - 26.8.2004, 11:34


--------------------
"Время проходит", - привыкли говорить вы по неверному пониманию. 
"Время стоит - проходите вы".
PM MAIL WWW ICQ MSN   Вверх
y0sh1
Дата 26.8.2004, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.8.2004

Репутация: нет
Всего: нет



Вобщем после дня эксперементов наваял я довольно простенький (и наверно всё же кривоватый) скрипт:
Код

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];
   $dir_size_mp3 += (stat("$root/$file"))[7] for (glob("$root/$file/*.mp3"));
              }
       }
 #print "$s_root : $dir_size\n";
}

...............

 [b]print "MP3 in: $dir_size_mp3\n\n";[/b]


Но что-то не катит... просто записывает в $dir_size_mp3 какое-то число... !?!?!? В чём может быть дело!?

Это сообщение отредактировал(а) y0sh1 - 26.8.2004, 18:35
PM MAIL   Вверх
ElectricalStorm
Дата 29.8.2004, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник Клуба
Сообщений: 547
Регистрация: 22.1.2004

Репутация: нет
Всего: 9



Код

1.

@list = <*.c>;
@list = glob("*.c");
You can also use readdir to extract the filenames manually:

или

opendir(DIR, $path);
@files = grep { /\.c$/ } readdir(DIR);
closedir(DIR);


2.  Для рекурсивных обходом директорий используйте File::Find

@ARGV = qw(.) unless @ARGV;
use File::Find;
find sub { print $File::Find::name, -d && "/", "\n" }, @ARGV;

3.

use File::Find;
@ARGV = (".") unless @ARGV;
my $sum = 0;
find sub { $sum += -s }, @ARGV;
print "@ARGV contains $sum bytes\n";



читаем CookBook smile.gif





--------------------
Нужно знать инструмент, которым пользуешься
PM MAIL   Вверх
y0sh1
Дата 30.8.2004, 12:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.8.2004

Репутация: нет
Всего: нет



Как при рекурсивном просмотре директорий более наглядно сделать "индикатор хода работы" так сказать - ну что бы видно было что процес идёт... в своём "сканере" пока сделал так:
Код
  if ($cc == 10){
     print "$root/$file\n";
     $cc = 0;
     }

те типа выводится на консоль каждая 10 папка\файл (все выводить слишком много)... причём на новой строке, думал прикрутить на одной:
Код
  if ($cc == 10){
     print "$root/$file[b]\r[/b]";
     $cc = 0;
     }

но в таком варианте что-то совсем ничего не вырисовывалось...
Может у кого есть более удачные варианты реализации !?
PM MAIL   Вверх
Secandr
Дата 30.8.2004, 12:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



Код
$cc++
  if ($cc == 10){
    print "$root/$file[b]\r[/b]";
    $cc = 0;
    }



--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
y0sh1
Дата 30.8.2004, 13:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.8.2004

Репутация: нет
Всего: нет



Secandr
прости не совсем понял...
\r - это я хотел выделить... код конечно:
Код
$cc++
 if ($cc == 10){
   print "$root/$file\r";
   $cc = 0;
   }


Это сообщение отредактировал(а) y0sh1 - 30.8.2004, 13:22
PM MAIL   Вверх
Secandr
Дата 30.8.2004, 13:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



вообще лучше писать что-то типа \r\n или <br> если в хтмл.

А вообще один топик - один вопрос


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
y0sh1
Дата 30.8.2004, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.8.2004

Репутация: нет
Всего: нет



Secandr
Цитата
вообще лучше писать что-то типа \r\n

типа это выведет список всех поддир и файлов в одной строке!?

Цитата
А вообще один топик - один вопрос

те если вопрос в русле уже созданой темы, то всё равно надо открывать новую!?
PM MAIL   Вверх
Secandr
Дата 30.8.2004, 13:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Связист
****


Профиль
Группа: Экс. модератор
Сообщений: 4043
Регистрация: 3.8.2003
Где: Russia, Volgograd

Репутация: 1
Всего: 39



тема была не про то как читать дирректорию, а про то как превратить глобальный указатель в локальный!
Добавлено @ 13:47
P.S. Открывай новый топик и подробно опиши проблему.


--------------------
Мышки плакали, кололись, но продолжали жрать кактусы (с) cisco
PM ICQ AOL   Вверх
y0sh1
Дата 30.8.2004, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 20
Регистрация: 26.8.2004

Репутация: нет
Всего: нет



Secandr
сорри если не туда запости, но искал по описанию темы, а там сказано чётко:
Цитата
Хочу написать о рекурсии
- у меня тоже рекурсия... и индикатор нужен... sad.gif
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Perl"
korob2001
sharq
  • В этом разделе обсуждаются общие вопросы по языку Perl
  • Если ваш вопрос относится к системному программированию, задавайте его здесь
  • Если ваш вопрос относится к CGI программированию, задавайте его здесь
  • Интерпретатор Perl можно скачать здесь ActiveState, O'REILLY, The source for Perl
  • Справочное руководство "Установка perl-модулей", можно скачать здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, korob2001, sharq.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Perl: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0920 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.