2010-01-27 2 views
24

Можно создать дубликат:
How can I list all of the files in a directory with Perl?Как я могу перебирать файлы в каталоге в Perl?

Я хочу перебрать несколько сотен файлов, все содержащиеся в одном каталоге. Как я могу это сделать в Perl?

+1

Разве этот вопрос не дублируется этим? http://stackoverflow.com/questions/1045792/how-can-i-list-all-of-the-files-in-a-directory-with-perl –

+1

@Leonardo Herrera Действительно, это так. Извините, я этого не помню. Голосование закрывается. –

+0

Я не вижу, как это дубликат. Вопрос задает вопрос о том, как перемещать файлы в каталоге. В отмеченном «дубликате» предлагается указать все файлы в каталоге. Совершенно другое. Зачем отмечать как дубликат? – CJ7

ответ

13

Вы можете использовать readdir или glob.

Или, вы можете использовать модуль, такой как Path::Class:

Обычно children() не будет включать в себя и родительские элементы. и .. (или их эквиваленты в системах, отличных от Unix), потому что это похоже на бизнес I'm-my-own-grandpa. Если вы хотите, чтобы все элементы каталога, включая эти специальные, передать истинное значение для всех параметров:

@c = $dir->children(); # Just the children 
@c = $dir->children(all => 1); # All entries 

Кроме того, есть no_hidden параметр, который исключает все нормально «скрытую» запись - на Unix это означает исключение все записи, которые начинаются с точки (.):

@c = $dir->children(no_hidden => 1); # Just normally-visible entries 

Или Path::Tiny:

@paths = path("/tmp")->children; 
@paths = path("/tmp")->children(qr/\.txt$/); 

Возвращает список Path::Tiny объектов для всех файлов и каталогов в пределах каталога. Исключает "." и ".." автоматически.

Если предоставляется необязательный аргумент qr//, он возвращает только объекты для дочерних имен, которые соответствуют данному регулярному выражению. Только имя базы используется для сравнения:

@paths = path("/tmp")->children(qr/^foo/); 
# matches children like the glob foo* 

Получение списка записей каталога в отходах массива некоторое количество памяти (в отличие от получения имени один файл за один раз), но лишь несколько сотен файлов , это вряд ли будет проблемой.

Path::Class переносится в операционные системы, отличные от * nix и Windows. С другой стороны, AFAIK, его экземпляры используют больше памяти, чем Path::Tiny экземпляров.

Если память является проблемой, вам лучше использовать readdir в цикле while.

+0

и reead_dir удаляет. и .. для вас и, если нужно, может префикс каталога в filename –

43
#!/usr/bin/perl -w 

@files = <*>; 
foreach $file (@files) { 
    print $file . "\n"; 
} 

Где

@files = <*>; 

может быть

@files = </var/www/htdocs/*>; 
@files = </var/www/htdocs/*.html>; 

и т.д.

+0

Это не будет отображать скрытые файлы (те, которые начинаются с точки) в GNU/Linux и, возможно, в других подобных операционных системах. – josch

17

Наслаждайтесь.

opendir(DH, "directory"); 
my @files = readdir(DH); 
closedir(DH); 

foreach my $file (@files) 
{ 
    # skip . and .. 
    next if($file =~ /^\.$/); 
    next if($file =~ /^\.\.$/); 

    # $file is the file used on this iteration of the loop 
} 
+1

спасибо! Я бы использовал 'next if ($ file = ~ /^.+$/);' хотя, чтобы избежать второго оператора;). – ashraf

+0

@ashraf regex должно быть /^\.+$/ вместо /^.+$/ – Rauf

+0

@Rauf да, я думаю, что вы правы! :) – ashraf

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