Perl File::Find::Rule для исключения одного каталога

У меня есть показанная ниже структура каталогов.

  1. Я хотел бы получить только имена проектов в моем @project. @project=('project1','project2');
  2. Я хотел бы исключить каталог OLD и его подкаталоги в @project
  3. Я хотел бы получить последний файл в подкаталогах для всех проектов в @project. т. е. для project1 последний файл находится в подкаталоге 2014, то есть foobar__2014_0916_248.txt

Как я могу сформулировать правило для достижения этого?

use strict;
use File::Find::Rule;
use Data::Dump;
my $output       = "/abc/def/ghi";
my @exclude_dirs = qw(OLD);
my @projects     = File::Find::Rule->directory->in("$output");
dd \@projects;

Моя структура каталога:

.
├── project1
│   ├── 2013
|        ├── file1_project1.txt
│   └── 2014
|         ├── foobar__2014_0912_255.txt
|         ├── foobar__2014_0916_248.txt
├── project2
│   ├── 2013
|        ├── file1_project2.txt
│   └── 2014
|         ├── foobarbaz__2014_0912_255.txt
|         ├── foobarbaz__2014_0916_248.txt
└── OLD
    └── foo.txt

person Jill448    schedule 17.09.2014    source источник
comment
Выполните два шага: 1) Найдите проекты и 2) Для каждого проекта найдите последний файл.   -  person ikegami    schedule 17.09.2014


Ответы (1)


Как предложил Икегами, просто сделайте это в два этапа.

  1. Сначала найдите названия своих проектов
  2. Второй найти последний файл

Следующее делает это, используя Path::Class и Path::Class::Rule

use strict;
use warnings;
use autodie;

use Path::Class;
use Path::Class::Rule;

my $testdir = dir('testing');

for my $project ( $testdir->children ) {
    next if !$project->is_dir() || $project->basename eq 'OLD';

    my $newest;

    my $next = Path::Class::Rule->new->file->iter($project);
    while ( my $file = $next->() ) {
        $newest = $file if !$newest || $file->stat->mtime > $newest->stat->mtime;
    }

    print "$project - $newest\n";
}

Выходы:

testing/project1 - testing/project1/2014/foobar__2014_0916_248.txt
testing/project2 - testing/project2/2014/foobarbaz__2014_0916_248.txt
person Miller    schedule 17.09.2014
comment
Я не смог установить Path::Class::Rule в своей системе. Пробовал с cpan> install Path::Class::Rule . Выдало ошибку Warning: Cannot install Path::Class::Rule;, don't know what it is. . Пробовал curl -k -L http://cpanmin.us | perl - --sudo Path::Class тоже выдал ошибку - person Jill448; 18.09.2014
comment
Не обязательно использовать Path::Class, мне просто нравится эта ветвь модулей, так как она легко позволяет работать с кросс-платформенной файловой системой. Вы можете легко выполнить итерацию по своему базовому каталогу, используя другой метод, и выполнить поиск в дереве проекта, используя File::Find::Rule. Просто может потребоваться больше кода. - person Miller; 18.09.2014
comment
Если вы хотите выяснить, почему вы не можете установить эти модули, возможно, начните новый вопрос, поскольку сообщение об ошибке, которое вы получаете, не имеет смысла. - person Miller; 18.09.2014
comment
Сделал это ... разместил еще один вопрос .. Спасибо - person Jill448; 18.09.2014
comment
@ sravs448 Ваш новый вопрос не имеет ничего общего с вашей ошибкой при установке Path::Class::Rule. Ну что ж. - person ThisSuitIsBlackNot; 18.09.2014
comment
@ sravs448 Я только что заметил, похоже, вы запустили install Path::Class::Rule; (с точкой с запятой) из оболочки CPAN. Отбросьте точку с запятой или просто запустите cpan install Path::Class::Rule из командной строки. - person ThisSuitIsBlackNot; 18.09.2014
comment
обязательно попробую так. Вот ссылка на мой новый вопрос. Дайте мне знать, если вы знаете решение. Спасибо . http://stackoverflow.com/questions/25900989/perl-filefindrule-to-find-latest-file-in-directories - person Jill448; 18.09.2014