2011-02-23 120 views
7

我有一個Perl腳本,我已經寫入搜索文件存在於我的Windows文件夾,遞歸。我輸入搜索文本作爲perl腳本運行時參數,以查找名稱中包含此文本的文件。 perl腳本如下:如何在Perl腳本中遞歸查找文件/文件夾?

use Cwd; 

$file1 = @ARGV[0];  

#@res1 = glob "*test*"; 
#@res1 = glob "$file1*"; 
@res1 = map { Cwd::abs_path($_) } glob "$file1*"; 
foreach (@res1) 
{ 
    print "$_\n"; 
} 

但是,這不是搜索所有的子目錄遞歸。我知道glob遞歸不匹配。
使用模塊File::Find和功能find(\&wanted, @directories);

所以嘗試,但我得到了一個錯誤說find()不確定。從我從幫助中讀到的內容,我認爲find()函數是在Perl安裝中默認定義的,具有一些基本代碼來查找文件夾/文件。這不正確嗎?

問題是,在上面的perl腳本中,如何遞歸搜索文件/文件夾?

第二個問題,我發現perldoc <module> help沒有關於在該模塊中使用某個函數的示例,這會使其清楚。

您能指出一些很好的幫助/文檔/書籍,它們使用來自不同perl模塊的各種perl函數,並清楚說明這些模塊函數的用法。

+0

我從這個問題http://stackoverflow.com/questions/4979310/extended-for-subdirectories-rename-files-and-directories-add-prefix方法可以幫助。這種情況下的任務是重命名目錄中的所有文件和文件夾以及所有子目錄。該方法可以很容易地修改爲您的使用。 –

回答

4

另一種方法是使用find2perl創建腳本爲你的開始。它可以打開查找命令,如

find . -type f -name "*test*" -print 

到等價的perl腳本。你只需要find2perl而不是find。它在引擎蓋下使用File :: Find,但可以讓你快速進入。

+0

謝謝。學習這個find2perl,並發現它非常有用的初學者獲得一些我cna玩的默認文件搜索腳本。 – goldenmean

+0

事實上,我認爲亞歷山德羅的答案確實更好,但讓你去find2perl真的很有用。 –

3

如果你不介意使用CPAN模塊,Path::Class能爲你做的工作:

use Path::Class; 

my @files; 
dir('.')->recurse(callback => sub { 
    my $file = shift; 
    if($file =~ /some text/) { 
     push @files, $file->absolute->stringify; 
    } 
}); 

for my $file (@files) { 
    # ... 
} 
+0

順便說一句,好消息,在我的測試中,這似乎也可以在OSX Lion(10.8.5)的全新副本上一直工作到我對OSX El Capitan(10.11)所做的最後一次測試,而無需安裝模塊。所以,如果你像我一樣,建立一個默認依賴這個工作的安裝程序 - 它的確如此。 – Volomike

15

另一個出色的模塊來使用是File::Find::Rule其中隱藏了一些的File::Find複雜性,同時暴露相同的豐富功能。

use File::Find::Rule; 
use Cwd; 

my $cwd = getcwd(); 
my $filelist; 

sub buildFileIndex { 
    open ($filelist, ">", "filelist.txt") || die $!; 

    # File find rule 
    my $excludeDirs = File::Find::Rule->directory 
           ->name('demo', 'test', 'sample', '3rdParty') # Provide specific list of directories to *not* scan 
           ->prune   # don't go into it 
           ->discard;  # don't report it 

    my $includeFiles = File::Find::Rule->file 
          ->name('*.txt', '*.csv'); # search by file extensions 

    my @files = File::Find::Rule->or($excludeDirs, $includeFiles) 
           ->in($cwd); 

    print $filelist map { "$_\n" } @files; 
    return \$filelist; 
} 
相關問題