Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Работа с файлами и каталогами


Автор: Jeka from Doneck 13.10.2008, 17:54
В ходе изучения языка в теме по работе с файлами и папками столкнулся со следующей задачей. Их несколько но это наиболее простая. 

Пройти по дереву каталогов,  начиная с текущего и вывести весь список файлов, содержащих внутри строки файла, у которых в пятом поле будет три буквы "а", не обязательно подряд, и имеющих шаблон имени файла, начинающегося с точки и содержащего внутри символы в заданной последовательности "set" и старше одного месяца с правами только на чтение

Буду очень признателен если поможете в изучении и решении данного примера. Думаю следующие за ней задания по примеру выполнить. 

Автор: gcc 13.10.2008, 18:01
сказали бы $ uname -r

а кто такое задал?

Автор: Jeka from Doneck 13.10.2008, 18:12
Никто не задал, я по сборнику по Perl беру это. Под редакцией Костина В.В. Вроде .

Щас вот после работы приехал, есть свободный вечер и думал поразбираться. 
И попросил помочь с решением написанной мною задачи.

Автор: arto 13.10.2008, 18:14
perldoc perlfunc nа предмет opendir, readdir, closedir, stat

Автор: Jeka from Doneck 13.10.2008, 18:21
arto Уважаемый, мне такой совет может мой 4 летний ребенок дать (в справке посмотреть), я не для этого условие написал, выше уже написал что необходимо. Те кто хорошо разбирается буду очень признателен в помощи.

Автор: gcc 13.10.2008, 18:21
про отрытие каталогов и файлов есть в книге "perl за 24 часа"
про массивы там тоже есть

вот скрипт загрузки файлов из каталога на сервер 
Код


#!/usr/bin/perl -w
$test = "http://bla-bla.ua/index.php?action=gallery&sa=add2";

opendir(TEMPDIR, '/usr/home/...../1g') ||
     die "bla-bla /tmp: $!";
@files=readdir TEMPDIR;
closedir(TEMPDIR);

for ($index=0; $index<@files; $index++) {

$file = "/usr/home/....../1g/$files[$index]";

use HTTP::Request::Common qw(POST);
use LWP::UserAgent;
use CGI qw(header -no_debug);

my $req = POST $test,
Content_Type => 'form-data',
Content      => [
        title => 'vasya',
    cat => '1',
       picture => [$file],
                ];
my $res = LWP::UserAgent->new->request($req);
print header, $res->is_success ? $res->content : $res->status_line;
print $req->as_string;

}

Автор: kavkaz 13.10.2008, 21:32
Уважаемый Jeka from Doneck, вы сами сказали что изучаете язык, стало быть вам не нужно готовое решение, давайте вы подробнее опишите проблему связанную с решением задачи а мы направим в нужное русло.
1. 
Цитата
Пройти по дереву каталогов,  начиная с текущего

2. 
Цитата
вывести весь список файлов, содержащих внутри строки файла, у которых в пятом поле будет три буквы "а", не обязательно подряд

тут я немного не понимаю что значит "пятое поле"...
3. 
Цитата
имеющих шаблон имени файла, начинающегося с точки и содержащего внутри символы в заданной последовательности "set" и старше одного месяца с правами только на чтение


предполагаю что пункт2 и пункт3 надо поменять местами...

так вот теперь по пунктам, где вы испытываете сложности?
просто если вы не знаете как считать в массив список содержащихся файлов, то так и напишите. Наверняка какие то моменты из задачи вы и сами способны решить

Автор: Jeka from Doneck 13.10.2008, 22:14
ВОт код программы 
Код

#!/usr/bin/perl
use locale;
my @dir_list = ("D:/LABS/FolderLab3");
scan_dir(\@dir_list);

sub scan_dir {
    my $dir  = shift @{$_[0]} || return;
    opendir(DIR, $dir) or die "Can't open directory '$dir': $!\n";
    while (my $file = readdir DIR) {
        next if $file =~ /^\.\.?$/;
          #  $data_sozd = -A "$dir/$file";

    if (-d "$dir/$file")
        {
            unshift(@{$_[0]},join("/",$dir,$file))
        } else {
#==============================ПРОВЕРКА ФАЙЛА================================================
        if (($file =~ m/^[^0-9][А-Яа-я]{2}[A-Za-z\.]{1,}$/i)) {
                 $ffx =  open(ML, "$dir/$file");
            $data_sozd = -M ML;
            print '111 '.$data_sozd." 222\n";
            if (   (-r "$dir/$file") && ($data_sozd>30) )
               {
 #-----------ПРОВЕРКА СОДЕРЖТМОГО ФАЙЛА--------------------
                $pr1 = 0;
                open(ML, "$dir/$file");
                while ($line = <ML>)
                {
                    $string = $string.$line;
                };
                $string =~ s/(\w+)/PrChars($&)/ige;
                sub PrChars{
                     my($text)=$&;
                    my($res,$chr,$i);
                     for($i=0;$i<=length($text);$i++)
                       {
                            $chr = substr($text,$i,1);
                            if ($i % 2 != 0)
                                                {    $res.=$chr;
                                                 if ($chr ne (lc($chr)))
                                                        { $pr1 = 1;
                                                        };
                                                }
                                        }
                 return $res;
                }
                close(ML);

                if ($pr1 == 0)
                                { # copy("$dir/$file", "D:/b.txt"); unlink ("$dir/$file");
                    print $data_sozd;
 # rename ("$dir/$file","D:/OUT/$file");
                            print ' |переносим файл: '."$dir/$file\n";
                }

 #---------------------------------------------------------
               };
        };
#============================================================================================
               } #end else
  }
    closedir(DIR);
    scan_dir($_[0]);
}


тут не совсем то задание, почти как требуется сделал. помогите доделать

Автор: ginnie 13.10.2008, 22:59
Jeka from Doneck, мы тут все хамы ужасные, очень любим над новичками поиздеваться, пока они еще опыта достаточно не набрались и сдачи дать не могут  smile 

Боюсь даже предположить, каким словом Вы меня назовете в ответ на предложение добавить в начало программы

Код

use strict;
use warnings;


это предложение тоже из секции "советы четырехлетних".

Автор: kavkaz 13.10.2008, 23:10
Jeka from Doneck, нет возможности да и желания (именно в такой последовательности) запускать и проверять программу...

вы конретно скажите где затык то?

и наберитесь терпения  smile  советом ginnie не пренебрегайте, а воспользуйтесь в первую очередь smile 

Автор: ginnie 13.10.2008, 23:26
P.S. вопросы на засыпку:

как по-вашему работает фрагмент

Код

$string =~ s/(\w+)/PrChars($&)/ige;
sub PrChars{
                     my($text)=$&;



у Вас так и задумано, что $string не инициализируется внутри вызова scan_dir() и сохраняет свое значение между вызовами?


зачем в рег. выражении 

Код

m/^[^0-9][А-Яа-я]{2}[A-Za-z\.]{1,}$/i


модификатор i ?

и самое главное: как мы можем помочь доделать, если Вы не написали, что у Вас не получается (т.е. что работает не так, как должно).

Автор: amg 14.10.2008, 07:28
Цитата(Jeka from Doneck @  13.10.2008,  17:54 Найти цитируемый пост)
Пройти по дереву каталогов,  начиная с текущего и вывести весь список файлов, содержащих внутри строки файла, у которых в пятом поле будет три буквы "а", не обязательно подряд, и имеющих шаблон имени файла, начинающегося с точки и содержащего внутри символы в заданной последовательности "set" и старше одного месяца с правами только на чтение
Я позволил себе немного переиначить условие в непонятных для меня местах
Код
my $set = 'set';
use File::Find;      # Пройти по дереву каталогов,
find(\&wanted, '.'); # начиная с текущего и
sub wanted {         # вывести весь список файлов,
  m/^\./     &&      # имеющих шаблон имени файла, начинающегося с точки и
  m/$set/o   &&      # содержащего внутри символы из переменной "$set"
  -M() > 30  &&      # старше одного месяца
  -r && ! -w &&      # с правами только на чтение
  sub{               # содержащих внутри только те строки, у которых  будет 
    open F, '<', shift or return 0;
    while (<F>) {
      my $field = (split)[4]; # в пятом поле (поле - последовательность непробельных символов)
      return 0 if $field=~tr/a/a/ != 3; # ровно три буквы "а"
    }
    close F;
    1
  }->($_)    &&
  print "$File::Find::name\n";
}

Автор: ginnie 14.10.2008, 11:32
amg, может еще добавить -f, чтобы не обрабатывать директории?

Автор: amg 14.10.2008, 13:40
Цитата(ginnie @  14.10.2008,  11:32 Найти цитируемый пост)
может еще добавить -f, чтобы не обрабатывать директории?
Это следовало бы сделать. А еще -- поставить условие ! -w на первое место, как самое редкое в "обычной жизни". smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)