2016-11-09 5 views
1

Я использую next if $file eq '.' $file eq '..';, чтобы найти файл в каталоге и подкаталоге (за исключением нескольких каталогов) и открыть файлы для поиска и замены. Но когда у меня есть точка в имени папки, она рассматривает папку как файл и говорит, что ее невозможно открыть. Я отфильтровал файлы с помощью -f, но он отсутствовал, чтобы показать файлы в основной папке.Найти файлы в папке и вложенной папке

Есть ли какой-нибудь рекурсивный способ найти папку и файлы, даже если у нее есть точка.

opendir my $dh, $folder or die "can't open the directory: $!"; 

while (defined(my $file = readdir($dh))) { 

    chomp $file; 

    next if $file eq '.' $file eq '..'; 

    { 
     if ($file ne 'fp') { 

      print "$folder\\$file"; 

      if ($file =~ m/(.[^\.]*)\.([^.]+$)/) { 
       ... 
      } 
     } 
    } 
} 
+0

ли вы забыли '' || (или) в 'следующем, если $ файла эк '' $ file eq '..'; '? Это должно быть 'next if ($ file eq '.' || $ file eq '..');' (хотя это не решает проблему рекурсии). – PerlDuck

+0

'chomp $ file;' не используется. Результаты от 'readdir' не имеют завершающей новой строки. – shawnhcorey

ответ

4

Вы можете использовать File::Find или File::Find::Rule как предложено Sobrique.

Это очень проста в использовании:

#!/usr/bin/perl 
use strict; 
use warnings; 
use File::Find; 
sub process_file { 
    next if (($_ eq '.') || ($_ eq '..')); 
    if (-d && $_ eq 'fp'){ 
     $File::Find::prune = 1; 
     return; 
    } 
    print "Directory: $_\n" if -d; 
    print "File: $_\n" if -f; 
    #Do search replace operations on file below 
} 
find(\&process_file, '/home/chankeypathak/Desktop/test.folder'); #provide list of paths as second argument. 

Я была ниже файловой структуры.

test.folder/test.txt 
test.folder/sub.folder 
test.folder/sub.folder/subfile.txt 
test.folder/fp 
test.folder/fp/fileinsidefp.txt 

И я ниже выхода

$ perl test.pl 
File: test.txt 
Directory: sub.folder 
File: subfile.txt 
+1

'File :: Find' - стандартный модуль; он поставляется с Perl. 'Файл :: Fins :: Rule' должен быть установлен из CPAN. Список стандартных модулей см. В разделе «perldoc perlmodlib». – shawnhcorey

+1

вместе с тем, что сказал @shawnhcorey, вы можете использовать 'corelist' в командной строке, чтобы проверить, является ли конкретный модуль ядром или нет:' corelist File :: Find' – stevieb

+0

Просто поставьте условный 'if (-d && $ _ eq 'FP') {следующий;} '. –

3

Да. Использовать File::Find::Rule

foreach my $file ( File::Find::Rule->file()->in(".")) { 

} 

... и это о нем. У вас есть опции для почти всех флагов 'filetest', поэтому file() для -f или readable() для -r.

Смежные вопросы