Как я могу выйти из функции рекурсивного поиска, когда будет найден определенный файл? - PullRequest
5 голосов
/ 19 декабря 2008

Я использую модуль File::Find для обхода дерева каталогов. Как только я нахожу определенный файл, я хочу прекратить поиск. Как я могу это сделать?

   find (\$processFile, $mydir);

   sub processFile() {
      if ($_ =~ /target/) {
         # How can I return from find here?
      }
   }

Ответы [ 6 ]

9 голосов
/ 19 декабря 2008

Похоже, вам придется умереть:

eval {
    find (\$processFile, $mydir);
};

if ( $@ ) {
   if ( $@ =~ m/^found it/ ) {
        # be happy
    }
    else ( $@ ) {
        die $@;
    }
}
else {
   # be sad
}


sub processFile() {
   if ($_ =~ /target/) {
      die 'found it';
   }
}
3 голосов
/ 19 декабря 2008

В дополнение к тому, что сказали все остальные, вы можете взглянуть на File-Find-Object , который является итеративным (и, как таковой, способным прерываться в середине) и способным к создание экземпляров (чтобы можно было инициировать и использовать несколько одновременно или создать экземпляр объекта FFO на основе во время другого сканирования и т. д.)

Недостатком является то, что он не является ядром, но имеет только Class :: Accessor в качестве зависимости и является чисто Perl, поэтому его не должно быть сложно установить.

Я должен предупредить вас, что я его сопровождающий, поэтому я могу быть немного предвзятым.

1 голос
/ 19 декабря 2008

Можете ли вы генерировать пользовательские исключения в Perl?

0 голосов
/ 19 декабря 2008

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

0 голосов
/ 19 декабря 2008

Я нашел эту ссылку:

http://www.perlmonks.org/index.pl?node_id=171367

Я скопировал один из скриптов в этот список постов, и это похоже на работу:

#! /usr/bin/perl -w

use strict;
use File::Find;

my @hits = ();
my $hit_lim = shift || 20;

find(
    sub {
        if( scalar @hits >= $hit_lim ) {
            $File::Find::prune = 1;
            return;
        }
        elsif( -d $_ ) {
            return;
        }
        push @hits, $File::Find::name;
    },
    shift || '.'
);

$, = "\n";
print @hits, "\n";

Похоже, что на самом деле поиск не пересекается с использованием $ File :: Find :: prune.

0 голосов
/ 19 декабря 2008

Функция processFile () должна возвращать true, если она находит файл, и false в противном случае. Таким образом, каждый раз, когда этот процесс вызывает сам, должен проверять это возвращаемое значение. Если это правда, какой-то рекурсивный вызов обнаружил файл, поэтому нет необходимости снова вызывать себя, и он также должен возвращать true. Если значение равно false, файл еще не найден, и он должен продолжить поиск.

...