2008-12-19 69 views
5

我正在使用File::Find模塊遍歷目錄樹。一旦我找到一個特定的文件,我想停止搜索。我怎樣才能做到這一點?一旦找到特定文件,我該如何擺脫遞歸查找功能?

find (\$processFile, $mydir); 

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

你的意思是「File :: Find」模塊,而不是「File :: Found」? – BrianH 2008-12-19 16:08:59

+0

是的,謝謝。我編輯了這個問題。 – MCS 2008-12-19 16:11:38

回答

9

好像你將不得不死;如果發現該文件

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

if ([email protected]) { 
    if ([email protected] =~ m/^found it/) { 
     # be happy 
    } 
    else ([email protected]) { 
     die [email protected]; 
    } 
} 
else { 
    # be sad 
} 


sub processFile() { 
    if ($_ =~ /target/) { 
     die 'found it'; 
    } 
} 
+0

這似乎工作。我對Perl很新穎 - 這是eval的典型用法嗎? – MCS 2008-12-19 16:38:50

1

你可以在Perl中拋出自定義異常嗎?

+0

我認爲這是一個模塊,但它是一個黑客。 – Keltia 2008-12-19 16:35:00

+0

只需將一個對象傳遞給die()而不是一個字符串。 – 2008-12-19 17:46:09

-4

功能processFile()應返回true,否則爲false。所以,processFile每次調用自己時都應該檢查這個返回值。如果這是真的,一些遞歸調用已經找到了該文件,所以不需要再次調用自己,並且它也必須返回true。如果它是假的,該文件還沒有找到,它應該繼續搜索。

-1

我發現這個鏈接:

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

你可以使用命名塊並跳轉到它,如果你找到你的結果(下一個,最後一個,它取決於你需要的)。

3

除了其他人所說的,你可能想看看File-Find-Object,它既是迭代的(因此可以在中間被中斷)並且能夠實例化(所以你可以啓動並使用幾個立即執行或實例化FFO對象,同時執行另一次掃描等)

它的缺點是它不是核心,但它只有Class :: Accessor作爲依賴項,並且是純Perl所以它不應該很難安裝。

我應該警告你我是它的維護者,所以我可能有點偏見。